[webbeans-commits] Webbeans SVN: r1903 - in test-harness/trunk: api and 76 other directories.

webbeans-commits at lists.jboss.org webbeans-commits at lists.jboss.org
Tue Mar 10 09:34:38 EDT 2009


Author: pete.muir at jboss.org
Date: 2009-03-10 09:34:37 -0400 (Tue, 10 Mar 2009)
New Revision: 1903

Added:
   test-harness/trunk/api/
   test-harness/trunk/api/pom.xml
   test-harness/trunk/api/src/
   test-harness/trunk/api/src/main/
   test-harness/trunk/api/src/main/java/
   test-harness/trunk/api/src/main/java/org/
   test-harness/trunk/api/src/main/java/org/jboss/
   test-harness/trunk/api/src/main/java/org/jboss/testharness/
   test-harness/trunk/api/src/main/java/org/jboss/testharness/api/
   test-harness/trunk/api/src/main/java/org/jboss/testharness/api/Configurable.java
   test-harness/trunk/api/src/main/java/org/jboss/testharness/api/Configuration.java
   test-harness/trunk/api/src/main/java/org/jboss/testharness/api/DeploymentException.java
   test-harness/trunk/api/src/main/java/org/jboss/testharness/api/TCK.java
   test-harness/trunk/api/src/main/java/org/jboss/testharness/api/TestLauncher.java
   test-harness/trunk/api/src/main/java/org/jboss/testharness/api/TestResult.java
   test-harness/trunk/api/src/main/java/org/jboss/testharness/spi/
   test-harness/trunk/api/src/main/java/org/jboss/testharness/spi/Containers.java
   test-harness/trunk/api/src/main/java/org/jboss/testharness/spi/StandaloneContainers.java
   test-harness/trunk/api/src/main/resources/
   test-harness/trunk/apl.txt
   test-harness/trunk/impl/
   test-harness/trunk/impl/pom.xml
   test-harness/trunk/impl/src/
   test-harness/trunk/impl/src/main/
   test-harness/trunk/impl/src/main/java/
   test-harness/trunk/impl/src/main/java/org/
   test-harness/trunk/impl/src/main/java/org/jboss/
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/AbstractTest.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/ExpectedException.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/ConfigurationImpl.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/PropertiesBasedConfigurationImpl.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/TCKImpl.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Artifact.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ArtifactDescriptor.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ArtifactGenerator.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ArtifactScanner.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Classes.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ExpectedDeploymentException.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/IntegrationTest.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Packaging.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/PackagingType.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Resource.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ResourceDescriptor.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Resources.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ear/
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ear/EarArtifactDescriptor.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ear/EjbJarArtifactDescriptor.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/jsr299/
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/jsr299/BeansXml.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/jsr299/JSR299ArtifactDescriptor.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/jsr299/TCKArtifactDescriptor.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/war/
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/war/WarArtifactDescriptor.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/BufferedListener.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/TestResultImpl.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/TestRunner.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/servlet/
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/servlet/ServletTestLauncher.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/servlet/ServletTestRunner.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/testng/
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/testng/DisableIntegrationTestsMethodSelector.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/testng/ExcludeIncontainerUnderInvestigationMethodSelector.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/testng/RemoveExpectedExceptionsAnnotationTransformer.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/DeploymentProperties.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/EnumerationIterable.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/EnumerationIterator.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/Files.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/Reflections.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/ResourceLoadingException.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/SimpleResourceLoader.java
   test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/Strings.java
   test-harness/trunk/impl/src/main/resources/
   test-harness/trunk/impl/src/main/resources/org/
   test-harness/trunk/impl/src/main/resources/org/jboss/
   test-harness/trunk/impl/src/main/resources/org/jboss/testharness/
   test-harness/trunk/impl/src/main/resources/org/jboss/testharness/impl/
   test-harness/trunk/impl/src/main/resources/org/jboss/testharness/impl/packaging/
   test-harness/trunk/impl/src/main/resources/org/jboss/testharness/impl/packaging/war/
   test-harness/trunk/impl/src/main/resources/org/jboss/testharness/impl/packaging/war/web.xml
   test-harness/trunk/impl/src/test/
   test-harness/trunk/impl/src/test/java/
   test-harness/trunk/impl/src/test/java/org/
   test-harness/trunk/impl/src/test/java/org/jboss/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/impl/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/impl/packaging/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/impl/packaging/ear/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/impl/packaging/ear/ejb-jar.xml
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/mock/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/mock/MockConfiguration.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/AbstractArtifactTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/Cow.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/DeclarativeEarTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/DummyTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/Fox.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/Cow.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DeclarativeStandaloneTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyClassesSpecifiedTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyCustomBeansXmlTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyEjbTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyIntegrationTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyResourcesSpecifiedTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyWarUnitTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/Fox.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/subpackage/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/subpackage/Rat.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/Cow.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/DeclarativeWarTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/DummyTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/Fox.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarativeArtifact/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/ear/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/ear/Cow.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/ear/DummyTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/ear/EarArtifactTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/packages/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/packages/ArtifactTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/packages/Cow.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/packages/Fox.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/subpackages/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/subpackages/Cow.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/subpackages/SubpackagesArtifactTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/subpackages/subpackge/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/subpackages/subpackge/Fox.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/tck/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/tck/Cow.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/tck/DummyTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/tck/TCKArtifactTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/war/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/war/Cow.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/war/DummyTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/war/WarArtifactTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/ArtifactScannerTest.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/DummyArtifact.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/subpackage/
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/subpackage/AnotherDummyArtifact.java
   test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/subpackage/NotAnArtifact.java
   test-harness/trunk/impl/src/test/resources/
   test-harness/trunk/impl/src/test/resources/org/
   test-harness/trunk/impl/src/test/resources/org/jboss/
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/impl/
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/impl/packaging/
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/impl/packaging/ear/
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/impl/packaging/ear/ejb-jar.xml
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/impl/packaging/jsr299/
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/impl/packaging/jsr299/default/
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/impl/packaging/jsr299/default/beans.xml
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarative/
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarative/standalone/
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarative/standalone/foo/
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarative/standalone/foo/foo.xml
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarative/standalone/my-web-beans.xml
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarative/war/
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarative/war/my-web.xml
   test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarativeArtifact/
   test-harness/trunk/pom.xml
   test-harness/trunk/readme.txt
   test-harness/trunk/src/
   test-harness/trunk/src/main/
   test-harness/trunk/src/main/assembly/
   test-harness/trunk/src/main/assembly/assembly.xml
Log:
initial import

Added: test-harness/trunk/api/pom.xml
===================================================================
--- test-harness/trunk/api/pom.xml	                        (rev 0)
+++ test-harness/trunk/api/pom.xml	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+JBoss, Home of Professional Open Source
+Copyright 2008, Red Hat Middleware LLC, and individual contributors
+by the @authors tag. See the copyright.txt in the distribution for a
+full listing of individual contributors.
+
+Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,  
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>org.jboss.test-harness</groupId>
+		<artifactId>jboss-test-harness-parent</artifactId>
+		<version>1.0.0-SNAPSHOT</version>
+	</parent>
+
+	<groupId>org.jboss.test-harness</groupId>
+	<artifactId>jboss-test-harness-api</artifactId>
+	<packaging>jar</packaging>
+	<name>JBoss Test Harness API</name>
+	<url>http://www.seamframework.org/WebBeans</url>
+   
+   <dependencies>
+
+   </dependencies>
+
+</project>

Added: test-harness/trunk/api/src/main/java/org/jboss/testharness/api/Configurable.java
===================================================================
--- test-harness/trunk/api/src/main/java/org/jboss/testharness/api/Configurable.java	                        (rev 0)
+++ test-harness/trunk/api/src/main/java/org/jboss/testharness/api/Configurable.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,17 @@
+package org.jboss.testharness.api;
+
+/**
+ * If you implement this interface, the TCK will inject the configuration into
+ * your implementation in the post-construct phase.
+ * 
+ * This interface can be implemented by any implementation of a TCK SPI.
+ * 
+ * @author Pete Muir
+ *
+ */
+public interface Configurable
+{
+   
+   public void setConfiguration(Configuration configuration);
+   
+}

Added: test-harness/trunk/api/src/main/java/org/jboss/testharness/api/Configuration.java
===================================================================
--- test-harness/trunk/api/src/main/java/org/jboss/testharness/api/Configuration.java	                        (rev 0)
+++ test-harness/trunk/api/src/main/java/org/jboss/testharness/api/Configuration.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,120 @@
+package org.jboss.testharness.api;
+
+import org.jboss.testharness.spi.Containers;
+import org.jboss.testharness.spi.StandaloneContainers;
+
+/**
+ * The configuration of the TCK.
+ * 
+ * The TCK may be configured using system properties or placed in a properties 
+ * file called META-INF/web-beans-tck.properties.
+ * 
+ * Porting package property names are the FQCN of the SPI class. Other property 
+ * names (one for each non-porting package SPI configuration option) are 
+ * specified here. The defaults are also listed here.
+ * 
+ * The TCK may also be configured programatically through this interface
+ * 
+ * @author Pete Muir
+ *
+ */
+public interface Configuration
+{
+   
+   public static final String OUTPUT_DIRECTORY_PROPERTY_NAME = "org.jboss.jsr299.tck.outputDirectory";
+   public static final String STANDALONE_PROPERTY_NAME = "org.jboss.jsr299.tck.standalone";
+   public static final String RUN_INTEGRATION_TESTS_PROPERTY_NAME = "org.jboss.jsr299.tck.runIntegrationTests";
+   public static final String CONNECT_TIMEOUT_PROPERTY_NAME = "org.jboss.jsr299.tck.connectTimeout";
+   public static final String LIBRARY_DIRECTORY_PROPERTY_NAME = "org.jboss.jsr299.tck.libraryDirectory";
+   public static final String HOST_PROPERTY_NAME = "org.jboss.jsr299.tck.host";
+   
+   public static final String DEFAULT_OUTPUT_DIRECTORY = System.getProperty("java.io.tmpdir") + "/jsr-299-tck/";
+   public static final boolean DEFAULT_STANDALONE = true;
+   public static final boolean DEFAULT_RUN_INTEGRATION_TESTS = false;
+   public static final int DEFAULT_CONNECT_DELAY = 5000;
+   public static final boolean DEFAULT_WRITE_DEPLOYED_ARCHIVES_TO_DISK = false;
+   public static final String DEFAULT_LIBRARY_DIRECTORY = null;
+   public static final String DEFAULT_HOST = "localhost:8080";
+   public static final int DEFAULT_CONNECT_RETRIES = 2;
+   
+   /**
+    * The output directory to put TCK specific output. The TestNG output 
+    * directory is configured via TestNG.
+    * 
+    * By default set to ${tmp}/jsr-299-tck
+    */
+   public String getOutputDirectory();
+   
+   /**
+    * Whether the TCK is in standalone mode or not.
+    * 
+    * By default true
+    */
+   public boolean isStandalone();
+   
+   /**
+    * When the TCK is running in container tests it will attempt to connect to
+    * the server every 200ms until the timeout is reached.
+    * 
+    * By default 5000ms
+    */
+   public int getConnectTimeout();
+   
+   /**
+    * The TCK allows additional libraries to be put in the deployed test
+    * artifacts (for example the porting package for the implementation). Any
+    * jars in this directory will be added to the deployed artifact.
+    * 
+    * By default no directory is used.
+    */
+   public String getLibraryDirectory();
+   
+   /**
+    * The TCK test launcher
+    * 
+    * @see TestLauncher
+    * 
+    */
+   public TestLauncher getInContainerTestLauncher();
+   
+   /**
+    * The implementation of {@link Containers} in use.
+    */
+   public Containers getContainers();
+   
+   /**
+    * Whether to run integration tests, by default false.
+    */
+   public boolean isRunIntegrationTests();
+
+   public void setOutputDirectory(String outputDirectory);
+
+   public void setStandalone(boolean standalone);
+
+   public void setConnectTimeout(int connectTimeout);
+
+   public void setLibraryDirectory(String libraryDir);
+
+   public void setInContainerTestLauncher(TestLauncher testLauncher);
+
+   public void setContainers(Containers containers);
+   
+   /**
+    * The implementation of {@link StandaloneContainers} in use.
+    */
+   public StandaloneContainers getStandaloneContainers();
+   
+   public void setStandaloneContainers(StandaloneContainers standaloneContainers);
+
+   public void setRunIntegrationTests(boolean runIntegrationTests);
+   
+   /**
+    * The TCK will use this as the remote host to connect to run in container 
+    * tests. By default localhost:8080
+    * 
+    */
+   public String getHost();
+   
+   public void setHost(String host);
+   
+}
\ No newline at end of file

Added: test-harness/trunk/api/src/main/java/org/jboss/testharness/api/DeploymentException.java
===================================================================
--- test-harness/trunk/api/src/main/java/org/jboss/testharness/api/DeploymentException.java	                        (rev 0)
+++ test-harness/trunk/api/src/main/java/org/jboss/testharness/api/DeploymentException.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,32 @@
+package org.jboss.testharness.api;
+
+/**
+ * Wraps the deployment exception, which can be obtained using 
+ * {@link #getCause()}
+ * @author Pete Muir
+ *
+ */
+public class DeploymentException extends Exception
+{
+
+   public DeploymentException()
+   {
+      super();
+   }
+
+   public DeploymentException(String arg0, Throwable arg1)
+   {
+      super(arg0, arg1);
+   }
+
+   public DeploymentException(String arg0)
+   {
+      super(arg0);
+   }
+
+   public DeploymentException(Throwable arg0)
+   {
+      super(arg0);
+   }
+   
+}

Added: test-harness/trunk/api/src/main/java/org/jboss/testharness/api/TCK.java
===================================================================
--- test-harness/trunk/api/src/main/java/org/jboss/testharness/api/TCK.java	                        (rev 0)
+++ test-harness/trunk/api/src/main/java/org/jboss/testharness/api/TCK.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,87 @@
+package org.jboss.testharness.api;
+
+
+
+/**
+ * Programmatic TCK control
+ * 
+ * @author Pete Muir
+ *
+ */
+public abstract class TCK
+{
+   
+   public static final String DUMP_ARTIFACTS_PROPERTY_NAME = "dumpArtifacts";
+   
+   public static final String DUMP_CONFIGURATION_PROPERTY_NAME = "dumpConfiguration";
+   
+   public static final String RUN_SUITE_PROPERTY_NAME = "runSuite";
+   
+   /**
+    * Obtain an instance of the TCK
+    * 
+    * @param configuration
+    *           the TCK configuration; if null, the TCK should try to load
+    *           configuration from system properties and
+    *           web-beans-tck.properties
+    * @return
+    */
+   public static final TCK newInstance()
+   {
+      TCK tCK;
+      try
+      {
+         tCK = (TCK) Class.forName("org.jboss.jsr299.tck.impl.TCKImpl").newInstance();
+      }
+      catch (InstantiationException e)
+      {
+         throw new IllegalStateException("WebBeansTCK cannot be run unless webbeans-tck-impl.jar is on the classpath", e);
+      }
+      catch (IllegalAccessException e)
+      {
+         throw new IllegalStateException("WebBeansTCK cannot be run unless webbeans-tck-impl.jar is on the classpath", e);
+      }
+      catch (ClassNotFoundException e)
+      {
+         throw new IllegalStateException("WebBeansTCK cannot be run unless webbeans-tck-impl.jar is on the classpath", e);
+      }      
+      return tCK;
+   }
+   
+   public static void main(String[] args)
+   {
+      if (isSystemPropertyTrue(DUMP_ARTIFACTS_PROPERTY_NAME))
+      {
+         TCK tck = newInstance();
+         tck.dumpArtifacts();
+      }
+      if (isSystemPropertyTrue(DUMP_CONFIGURATION_PROPERTY_NAME))
+      {
+         System.out.println(newInstance().getConfiguration());
+      }
+   }
+
+   protected TCK()
+   {
+   }
+   
+   /**
+    * Initiate a dump of all TCK artifacts
+    * 
+    */
+   public abstract void dumpArtifacts(); 
+   
+   /**
+    * Get the current configuration
+    * 
+    * @return
+    */
+   public abstract Configuration getConfiguration();
+   
+   private static boolean isSystemPropertyTrue(String propertyName)
+   {
+      String value = System.getProperty(propertyName);
+      return value != null && Boolean.valueOf(value);
+   }
+   
+}

Added: test-harness/trunk/api/src/main/java/org/jboss/testharness/api/TestLauncher.java
===================================================================
--- test-harness/trunk/api/src/main/java/org/jboss/testharness/api/TestLauncher.java	                        (rev 0)
+++ test-harness/trunk/api/src/main/java/org/jboss/testharness/api/TestLauncher.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,38 @@
+package org.jboss.testharness.api;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+/**
+ * Allow the TCK to launch a test remotely in a container.
+ * 
+ * The TCK provides a built in launcher for use in an environment where Servlet
+ * is available such as EE6, EE5 or EE6 Web Profile. This can be used by 
+ * specifying:
+ * 
+ * org.jboss.jsr299.tck.api.TestLauncher=org.jboss.jsr299.tck.impl.runner.servlet.ServletTestLauncher
+ * 
+ * A Servlet suitable for launching tests is included in the artifacts produced
+ * by the JSR299 TCK.
+ * 
+ * @author Pete Muir
+ *
+ */
+public interface TestLauncher
+{
+   
+   public static final String PROPERTY_NAME = TestLauncher.class.getName();
+   
+   /**
+    * Launch a test remotely, returning the result to the TCK.
+    * 
+    * @param method
+    *           the method to launch
+    * @return the test result
+    * @throws IOException
+    *            if a communication error occured with the server. This will
+    *            cause the test to fail
+    */
+   public TestResult launchTest(Method method) throws IOException;
+   
+}

Added: test-harness/trunk/api/src/main/java/org/jboss/testharness/api/TestResult.java
===================================================================
--- test-harness/trunk/api/src/main/java/org/jboss/testharness/api/TestResult.java	                        (rev 0)
+++ test-harness/trunk/api/src/main/java/org/jboss/testharness/api/TestResult.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,47 @@
+package org.jboss.testharness.api;
+
+import java.io.Serializable;
+
+/**
+ * A test result which may be serialized for communicate between client and
+ * server
+ * 
+ * @author Pete Muir
+ *
+ */
+public interface TestResult extends Serializable
+{
+   
+   /**
+    * The test status
+    * @author Pete Muir
+    *
+    */
+   public enum Status
+   {
+      /**
+       * The test passed
+       */
+      PASSED,
+      /**
+       * The test failed
+       */
+      FAILED,
+      /**
+       * The test was skipped due to some deployment problem
+       */
+      SKIPPED;
+   }
+   
+   /**
+    * Get the status of this test
+    */
+   public Status getStatus();
+   
+   /**
+    * If the test failed, the exception that was thrown. It does not need to be
+    * the root cause.
+    */
+   public Throwable getThrowable();
+   
+}
\ No newline at end of file

Added: test-harness/trunk/api/src/main/java/org/jboss/testharness/spi/Containers.java
===================================================================
--- test-harness/trunk/api/src/main/java/org/jboss/testharness/spi/Containers.java	                        (rev 0)
+++ test-harness/trunk/api/src/main/java/org/jboss/testharness/spi/Containers.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,85 @@
+package org.jboss.testharness.spi;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.jboss.testharness.api.DeploymentException;
+
+/**
+ * Incontainer mode deployment related operations
+ * 
+ * The TCK porting package must provide an implementation of this interface
+ * which is suitable for the target implementation and application server
+ * 
+ * @author Pete Muir
+ * 
+ */
+public interface Containers
+{
+   
+   public static final String PROPERTY_NAME = Containers.class.getName();
+   
+   /**
+    * The war/ear to deploy to the container, it should be read using a
+    * JarInputStream.
+    * 
+    * For a successful deployment, a symmetric {@link #undeploy(String)} will be
+    * called.
+    * 
+    * @see #undeploy(String)
+    * 
+    * @param archive
+    *           the archive
+    * @param name
+    *           the name the TCK uses to refer to this archive, unique within
+    *           this tck run
+    * @throws DeploymentException
+    *            if any exceptions are encountered during deployment, they
+    *            should be rethrown wrapped in a {@link DeploymentException}.
+    *            Note that the TCK checks deployment exceptions.
+    * @throws IOException
+    *            if any communication problems with the server occur during
+    *            deployment. These will cause the test suite to fail.
+    */
+   public void deploy(InputStream archive, String name) throws DeploymentException, IOException;
+   
+   /**
+    * Undeploy the war/ear from the container.
+    * 
+    * @see #deploy(InputStream, String)
+    * 
+    * @param name
+    *           the name the TCK uses to refer to this archive, unique within
+    *           this tck run
+    * @throws IOException
+    *            if any communication problems with the server occur during
+    *            deployment. These will cause the test suite to fail.
+    */
+   public void undeploy(String name) throws IOException;
+   
+   /**
+    * Called before the TCK starts executing the testsuite, but after the suite
+    * has been configured.
+    * 
+    * A TCK suite lifecycle callback, useful for setting up the container. This
+    * method may be a no-op if no setup is required.
+    * 
+    * @throws IOException
+    *            if any communication problems with the server occur during
+    *            setup. These will cause the test suite to fail.
+    */
+   public void setup() throws IOException;
+   
+   /**
+    * Called after the TCK finishes executing the testsuite.
+    * 
+    * A TCK suite lifecycle callback, useful for cleaning up and shutting down
+    * the container. This method may be a no-op if no setup is required.
+    * 
+    * @throws IOException
+    *            if any communication problems with the server occur during
+    *            cleanup. These will cause the test suite to fail.
+    */
+   public void cleanup() throws IOException;
+   
+}
\ No newline at end of file

Added: test-harness/trunk/api/src/main/java/org/jboss/testharness/spi/StandaloneContainers.java
===================================================================
--- test-harness/trunk/api/src/main/java/org/jboss/testharness/spi/StandaloneContainers.java	                        (rev 0)
+++ test-harness/trunk/api/src/main/java/org/jboss/testharness/spi/StandaloneContainers.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,92 @@
+package org.jboss.testharness.spi;
+
+import java.net.URL;
+
+import org.jboss.testharness.api.DeploymentException;
+
+/**
+ * Standalone mode deployment related operations. If the TCK is placed in
+ * standalone mode, unit tests will be deployed via this interface.
+ * 
+ * You must implement this as part of the porting package if you intend to run
+ * the TCK in standalone mode
+ * 
+ * @author Pete Muir
+ *
+ */
+public interface StandaloneContainers
+{
+   
+   public static final String PROPERTY_NAME = StandaloneContainers.class.getName();
+   
+   /**
+    * <p>Bootstrap the container by registering Beans and Observers, raising 
+    * @Initialized event, validating the deployment, and raising the 
+    * @Deployed event.</p>
+    * 
+    * <p>Any classes passed in should be fully deployed. This includes:</p>
+    * 
+    * <ul>
+    * <li>Simple beans</li>
+    * <li>Session beans</li>
+    * <li>Producer methods and producer fields</li>
+    * <li>Observer methods</li>
+    * <li>support for Event and Instance injection points</li> 
+    * </ul>
+    * 
+    * The container should be in an fully initialized state when the
+    * method returns
+    * 
+    * @param classes the classes to deploy
+    */
+   public void deploy(Iterable<Class<?>> classes) throws DeploymentException;
+   
+   /**
+    * <p>Bootstrap the container for a test by registering Beans and Observers, 
+    * raising @Initialized event, validating the deployment, and raising the 
+    * @Deployed event.</p>
+    * 
+    * <p>Any classes passed in should be fully deployed. This includes:</p>
+    * 
+    * <ul>
+    * <li>Simple beans</li>
+    * <li>Session beans</li>
+    * <li>Producer methods and producer fields</li>
+    * <li>Observer methods</li>
+    * <li>support for Event and Instance injection points</li> 
+    * </ul>
+    * 
+    * The container should be in an fully initialized state when the
+    * method returns
+    * 
+    * @param classes the classes to deploy
+    * @param beansXmls the beans.xml files to deploy
+    */
+   public void deploy(Iterable<Class<?>> classes, Iterable<URL> beansXmls) throws DeploymentException;
+   
+   /**
+    * Cleanup the container after this test
+    * 
+    */
+   public void undeploy();
+   
+   /**
+    * Called before the TCK starts executing the testsuite, but after the suite
+    * has been configured.
+    * 
+    * A TCK suite lifecycle callback, useful for setting up the container. This
+    * method may be a no-op if no setup is required. 
+    * 
+    */
+   public void setup();
+   
+   /**
+    * Called after the TCK finishes executing the testsuite.
+    * 
+    * A TCK suite lifecycle callback, useful for cleaning up and shutting down
+    * the container. This method may be a no-op if no setup is required.
+    * 
+    */
+   public void cleanup();
+   
+}

Added: test-harness/trunk/apl.txt
===================================================================
--- test-harness/trunk/apl.txt	                        (rev 0)
+++ test-harness/trunk/apl.txt	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

Added: test-harness/trunk/impl/pom.xml
===================================================================
--- test-harness/trunk/impl/pom.xml	                        (rev 0)
+++ test-harness/trunk/impl/pom.xml	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+   <parent>
+      <artifactId>jboss-test-harness-parent</artifactId>
+      <groupId>org.jboss.test-harness</groupId>
+      <version>1.0.0-SNAPSHOT</version>
+   </parent>
+   <modelVersion>4.0.0</modelVersion>
+   <groupId>org.jboss.test-harness</groupId>
+   <artifactId>jboss-test-harness</artifactId>
+   <name>JBoss Test Harness</name>
+   
+   <dependencies>
+
+      <dependency>
+         <groupId>org.jboss.test-harness</groupId>
+         <artifactId>jboss-test-harness-api</artifactId>
+      </dependency>
+
+      <dependency>
+         <groupId>org.testng</groupId>
+         <artifactId>testng</artifactId>
+         <classifier>jdk15</classifier>
+      </dependency>
+      
+      <dependency>
+         <groupId>log4j</groupId>
+         <artifactId>log4j</artifactId>
+         <version>1.2.14</version>
+      </dependency>
+      
+      <dependency>
+         <groupId>javax.servlet</groupId>
+         <artifactId>servlet-api</artifactId>
+         <optional>true</optional>
+      </dependency>
+
+   </dependencies>
+   
+   <build>
+      <plugins>
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-dependency-plugin</artifactId>
+            <executions>
+               <execution>
+                  <id>copy-in-container-dependencies</id>
+                  <phase>generate-test-resources</phase>
+                  <goals>
+                     <goal>copy</goal>
+                  </goals>
+                  <configuration>
+                     <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory>
+                     <stripVersion>true</stripVersion>
+                     <artifactItems>
+                        <artifactItem>
+                           <groupId>org.jboss.test-harness</groupId>
+                           <artifactId>jboss-test-harness-api</artifactId>
+                           <overWrite>true</overWrite>
+                        </artifactItem>
+                        <artifactItem>
+                           <groupId>org.testng</groupId>
+                           <artifactId>testng</artifactId>
+                           <classifier>jdk15</classifier>
+                        </artifactItem>
+                     </artifactItems>
+                  </configuration>
+               </execution>
+            </executions>
+         </plugin>
+      </plugins>
+   	<defaultGoal>install</defaultGoal>
+   </build>
+
+</project>

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/AbstractTest.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/AbstractTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/AbstractTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,267 @@
+package org.jboss.testharness;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.jboss.testharness.api.Configuration;
+import org.jboss.testharness.api.DeploymentException;
+import org.jboss.testharness.api.TestResult;
+import org.jboss.testharness.api.TestResult.Status;
+import org.jboss.testharness.impl.ConfigurationImpl;
+import org.jboss.testharness.impl.packaging.ArtifactGenerator;
+import org.jboss.testharness.impl.packaging.jsr299.TCKArtifactDescriptor;
+import org.testng.IHookCallBack;
+import org.testng.IHookable;
+import org.testng.ITestContext;
+import org.testng.ITestResult;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeSuite;
+
+public abstract class AbstractTest implements IHookable
+{
+   
+   private static Logger log = Logger.getLogger(AbstractTest.class);
+
+   private static boolean inContainer = false;
+   
+   public static boolean isInContainer()
+   {
+      return inContainer;
+   }
+   
+   public static void setInContainer(boolean inContainer)
+   {
+      AbstractTest.inContainer = inContainer;
+   }
+
+   private TCKArtifactDescriptor artifact;
+   private DeploymentException deploymentException;
+   private boolean skipTest = false;
+   
+   private boolean isSuiteDeployingTestsToContainer()
+   {
+      return !isInContainer() && (!getCurrentConfiguration().isStandalone() || getCurrentConfiguration().isRunIntegrationTests()); 
+   }
+   
+   private void generateArtifact()
+   {
+      // If we are in the container, the artifact is already built
+      if (!isInContainer())
+      {
+         ArtifactGenerator generator = new ArtifactGenerator(getCurrentConfiguration());
+         artifact = generator.createArtifact(this.getClass());
+      }
+   }
+   
+   private boolean isDeployToContainerNeeded()
+   {
+      /*
+       *    If this isn't running inside the container
+       *  AND
+       *    there is an artifact to deploy
+       *  AND
+       *    EITHER
+       *      we are in standalone mode and it isn't a unit test
+       *    OR
+       *      we aren't in standalone mode
+       *  THEN
+       *    we need to deploy 
+       */
+      return !isInContainer() && artifact != null && ((getCurrentConfiguration().isStandalone() && !artifact.isUnit() && getCurrentConfiguration().isRunIntegrationTests()) || !getCurrentConfiguration().isStandalone());
+   }
+   
+   private void deployArtifact()
+   {
+      try
+      {
+         if (isDeployToContainerNeeded())
+         {
+            InputStream jar = null;
+            try
+            {
+               jar = artifact.getJarAsStream();
+               getCurrentConfiguration().getContainers().deploy(jar, artifact.getDefaultName());
+            }
+            finally
+            {
+               if (jar != null)
+               {
+                  jar.close();
+               }
+            }
+         }
+         else if (artifact != null && artifact.isUnit())
+         {
+            Set<Class<?>> classes = artifact.getClasses();
+            getCurrentConfiguration().getStandaloneContainers().deploy(classes, Arrays.asList(artifact.getBeansXml().getSource()));
+         }
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException("Error connecting to the container", e);
+      }
+      catch (DeploymentException e)
+      {
+         deploymentException = e;
+      }
+      if (artifact != null && artifact.getExpectedDeploymentException() != null)
+      {
+         if (deploymentException != null)
+         {
+            if (isThrowablePresent(artifact.getExpectedDeploymentException(), deploymentException.getCause()))
+            {
+               // We expect this exception, so ignore it
+               deploymentException = null;
+               skipTest = true;
+            }
+         }
+         else
+         {
+            this.deploymentException = new DeploymentException(new ExpectedException("Expected exception " + artifact.getExpectedDeploymentException() + " but none was thrown"));
+         }
+      }
+   }
+   
+   private void undeployArtifact() throws Exception
+   {
+      if (isDeployToContainerNeeded())
+      {
+         getCurrentConfiguration().getContainers().undeploy(artifact.getDefaultName());
+      }
+      if (getCurrentConfiguration().isStandalone() && artifact != null && artifact.isUnit())
+      {
+         getCurrentConfiguration().getStandaloneContainers().undeploy();
+      }
+   }
+   
+   private void checkAssertionsEnabled()
+   {
+      boolean assertionsEnabled = false;
+      try
+      {
+         assert false;
+      }
+      catch (AssertionError error) 
+      {
+         assertionsEnabled = true;
+      }
+      if (!assertionsEnabled)
+      {
+         throw new IllegalStateException("Assertions must be enabled!");
+      }
+   }
+   
+   @BeforeSuite(alwaysRun=true)
+   public void beforeSuite(ITestContext context) throws Exception
+   {
+      if (isSuiteDeployingTestsToContainer())
+      {
+         getCurrentConfiguration().getContainers().setup();
+      }
+      if (getCurrentConfiguration().isStandalone())
+      {
+         getCurrentConfiguration().getStandaloneContainers().setup();
+      }
+      checkAssertionsEnabled();
+   }
+   
+   
+   @AfterSuite(alwaysRun=true)
+   public void afterSuite() throws Exception
+   {
+      if (isSuiteDeployingTestsToContainer())
+      {
+         getCurrentConfiguration().getContainers().cleanup();
+      }
+      if (getCurrentConfiguration().isStandalone())
+      {
+         getCurrentConfiguration().getStandaloneContainers().cleanup();
+      }
+   }
+   
+   @BeforeClass(alwaysRun=true)
+   public void beforeClass() throws Throwable
+   {
+      generateArtifact();
+      deployArtifact();
+      
+   }
+   
+   @AfterClass(alwaysRun=true)
+   public void afterClass() throws Exception
+   {
+      undeployArtifact();
+      this.artifact = null;
+      this.deploymentException = null;
+      skipTest = false;
+   }
+
+
+   public void run(IHookCallBack callback, ITestResult testResult)
+   {
+      if (artifact == null && !isInContainer())
+      {
+         log.warn("Non @Artifact-test for testcase " + testResult.getMethod());
+      }
+	   if (deploymentException != null)
+	   {
+		   testResult.setThrowable(deploymentException.getCause());
+	   }
+	   else if ((!isDeployToContainerNeeded() || artifact.isRunLocally())  && !skipTest)
+      {
+         callback.runTestMethod(testResult);
+         if (!getCurrentConfiguration().isStandalone() && !isInContainer() && !artifact.isRunLocally())
+         {
+            log.warn("Running testcase locally " + testResult.getMethod());
+         }
+      }
+      else if (!skipTest)
+      {
+         try
+         {
+            TestResult result = getCurrentConfiguration().getInContainerTestLauncher().launchTest(testResult.getMethod().getMethod());
+            if (result.getStatus().equals(Status.FAILED) || result.getStatus().equals(Status.SKIPPED))
+            {
+               testResult.setThrowable(result.getThrowable());
+               testResult.setStatus(ITestResult.FAILURE);
+            }
+         }
+         catch (IOException e)
+         {
+            throw new RuntimeException("Error connecting to the container", e);
+         }
+      }
+   }
+   
+   protected static Configuration getCurrentConfiguration()
+   {
+      return ConfigurationImpl.get();
+   }
+   
+   protected String getContextPath()
+   {
+      return "http://" + getCurrentConfiguration().getHost() + "/" + this.getClass().getName() + "/";
+   }
+   
+   
+   protected static boolean isThrowablePresent(Class<? extends Throwable> throwableType, Throwable throwable)
+   {
+      if (throwable == null)
+      {
+         return false;
+      }
+      else if (throwableType.isAssignableFrom(throwable.getClass()))
+      {
+         return true;
+      }
+      else
+      {
+         return isThrowablePresent(throwableType, throwable.getCause()); 
+      }
+   }
+}
\ No newline at end of file

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/ExpectedException.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/ExpectedException.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/ExpectedException.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,34 @@
+package org.jboss.testharness;
+
+/**
+ * Thrown if an exception was expected, but non occurred
+ * 
+ * @author Pete Muir
+ *
+ */
+public class ExpectedException extends RuntimeException
+{
+
+   public ExpectedException()
+   {
+      super();
+   }
+
+   public ExpectedException(String message, Throwable cause)
+   {
+      super(message, cause);
+   }
+
+   public ExpectedException(String message)
+   {
+      super(message);
+   }
+
+   public ExpectedException(Throwable cause)
+   {
+      super(cause);
+   }
+   
+   
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/ConfigurationImpl.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/ConfigurationImpl.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/ConfigurationImpl.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,166 @@
+package org.jboss.testharness.impl;
+
+import org.jboss.testharness.api.Configuration;
+import org.jboss.testharness.api.TestLauncher;
+import org.jboss.testharness.spi.Containers;
+import org.jboss.testharness.spi.StandaloneContainers;
+
+public class ConfigurationImpl implements Configuration
+{
+   
+   private static Configuration current;
+   public static Configuration get()
+   {
+      if (ConfigurationImpl.current == null)
+      {
+         ConfigurationImpl.current = new PropertiesBasedConfigurationImpl().loadSPIImplementation();
+      }
+      return ConfigurationImpl.current;
+   }
+   
+   private String outputDirectory;
+   private boolean standalone;
+   private boolean runIntegrationTests;
+   private int connectTimeout;
+   private String libraryDirectory;
+   private TestLauncher testLauncher;
+   private Containers containers;
+   private StandaloneContainers standaloneContainers;
+   private String host;
+   
+   protected ConfigurationImpl()
+   {
+   }
+   
+   public ConfigurationImpl(Configuration configuration)
+   {
+      this.outputDirectory = configuration.getOutputDirectory();
+      this.standalone = configuration.isStandalone();
+      this.runIntegrationTests = configuration.isRunIntegrationTests();
+      this.connectTimeout = configuration.getConnectTimeout();
+      this.libraryDirectory = configuration.getLibraryDirectory();
+      this.testLauncher = configuration.getInContainerTestLauncher();
+      this.containers = configuration.getContainers();
+      this.standaloneContainers = configuration.getStandaloneContainers();
+      this.host = configuration.getHost();
+   }
+
+   public String getOutputDirectory()
+   {
+      return outputDirectory;
+   }
+   
+   public void setOutputDirectory(String outputDirectory)
+   {
+      this.outputDirectory = outputDirectory;
+   }
+   
+   public boolean isStandalone()
+   {
+      return standalone;
+   }
+   
+   public void setStandalone(boolean standalone)
+   {
+      this.standalone = standalone;
+   }
+
+   public int getConnectTimeout()
+   {
+      return connectTimeout;
+   }
+   
+   public void setConnectTimeout(int deploymentDelay)
+   {
+      this.connectTimeout = deploymentDelay;
+   }
+   
+   public String getLibraryDirectory()
+   {
+      return libraryDirectory;
+   }
+   
+   public void setLibraryDirectory(String libraryDir)
+   {
+      this.libraryDirectory = libraryDir;
+   }
+   
+   public TestLauncher getInContainerTestLauncher()
+   {
+      return testLauncher;
+   }
+   
+   public void setInContainerTestLauncher(TestLauncher testLauncher)
+   {
+      this.testLauncher = testLauncher;
+   }
+
+   public Containers getContainers()
+   {
+      return containers;
+   }
+
+   public void setContainers(Containers containers)
+   {
+      this.containers = containers;
+   }
+
+   public boolean isRunIntegrationTests()
+   {
+      return runIntegrationTests;
+   }
+
+   public void setRunIntegrationTests(boolean runIntegrationTests)
+   {
+      this.runIntegrationTests = runIntegrationTests;
+   }
+   
+   public StandaloneContainers getStandaloneContainers()
+   {
+      return standaloneContainers;
+   }
+   
+   public void setStandaloneContainers(StandaloneContainers standaloneContainers)
+   {
+      this.standaloneContainers = standaloneContainers;
+   }
+
+   public String getHost()
+   {
+      return host;
+   }
+
+   public void setHost(String host)
+   {
+      this.host = host;
+   }
+
+   public TestLauncher getTestLauncher()
+   {
+      return testLauncher;
+   }
+
+   public void setTestLauncher(TestLauncher testLauncher)
+   {
+      this.testLauncher = testLauncher;
+   }   
+   
+   @Override
+   public String toString()
+   {
+      StringBuilder configuration = new StringBuilder();
+      configuration.append("Test harness configuration\n");
+      configuration.append("-----------------\n");
+      configuration.append("\tContainers: ").append(getContainers()).append("\n");
+      configuration.append("\tConnect Timeout: ").append(getConnectTimeout()).append("\n");
+      configuration.append("\tHost: ").append(getHost()).append("\n");
+      configuration.append("\tLibrary Directory: ").append(getLibraryDirectory()).append("\n");
+      configuration.append("\tOutput Directory: ").append(getOutputDirectory()).append("\n");
+      configuration.append("\tRun Integration Tests: ").append(isRunIntegrationTests()).append("\n");
+      configuration.append("\tStandalone: ").append(isStandalone()).append("\n");
+      configuration.append("\tTest Launcher: ").append(getTestLauncher()).append("\n");
+      
+      return configuration.toString();
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/PropertiesBasedConfigurationImpl.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/PropertiesBasedConfigurationImpl.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/PropertiesBasedConfigurationImpl.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,45 @@
+package org.jboss.testharness.impl;
+
+import org.jboss.testharness.api.Configurable;
+import org.jboss.testharness.api.TestLauncher;
+import org.jboss.testharness.impl.util.DeploymentProperties;
+import org.jboss.testharness.spi.Containers;
+import org.jboss.testharness.spi.StandaloneContainers;
+
+public class PropertiesBasedConfigurationImpl extends ConfigurationImpl
+{
+   
+   private final DeploymentProperties deploymentProperties;
+   
+   public PropertiesBasedConfigurationImpl()
+   {
+      this.deploymentProperties = new DeploymentProperties();
+      
+      setOutputDirectory(deploymentProperties.getStringValue(OUTPUT_DIRECTORY_PROPERTY_NAME, DEFAULT_OUTPUT_DIRECTORY, false));
+      setStandalone(deploymentProperties.getBooleanValue(STANDALONE_PROPERTY_NAME, DEFAULT_STANDALONE, false));
+      setRunIntegrationTests(deploymentProperties.getBooleanValue(RUN_INTEGRATION_TESTS_PROPERTY_NAME, DEFAULT_RUN_INTEGRATION_TESTS, false));
+      setConnectTimeout(deploymentProperties.getIntValue(CONNECT_TIMEOUT_PROPERTY_NAME, DEFAULT_CONNECT_DELAY, false));
+      setLibraryDirectory(deploymentProperties.getStringValue(LIBRARY_DIRECTORY_PROPERTY_NAME, DEFAULT_LIBRARY_DIRECTORY, false));
+      setHost(deploymentProperties.getStringValue(HOST_PROPERTY_NAME, DEFAULT_HOST, false));
+   }
+   
+   public PropertiesBasedConfigurationImpl loadSPIImplementation()
+   {
+      setInContainerTestLauncher(getInstanceValue(TestLauncher.PROPERTY_NAME, TestLauncher.class, isRunIntegrationTests() || !isStandalone()));
+      setContainers(getInstanceValue(Containers.PROPERTY_NAME, Containers.class, !isStandalone() || isRunIntegrationTests()));
+      setStandaloneContainers(getInstanceValue(StandaloneContainers.PROPERTY_NAME, StandaloneContainers.class, isStandalone()));
+      
+      return this;
+   }
+   
+   private <T> T getInstanceValue(String propertyName, Class<T> expectedType, boolean required)
+   {
+      T instance = deploymentProperties.getInstanceValue(propertyName, expectedType, required);
+      if (instance instanceof Configurable)
+      {
+         ((Configurable) instance).setConfiguration(this);
+      }
+      return instance;
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/TCKImpl.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/TCKImpl.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/TCKImpl.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,77 @@
+package org.jboss.testharness.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.jboss.testharness.api.Configuration;
+import org.jboss.testharness.api.TCK;
+import org.jboss.testharness.impl.packaging.ArtifactGenerator;
+import org.testng.TestNG;
+import org.testng.xml.Parser;
+import org.testng.xml.XmlSuite;
+import org.xml.sax.SAXException;
+
+public class TCKImpl extends TCK
+{
+   
+   private static Logger log = Logger.getLogger(TCKImpl.class);
+   
+   protected void runUnitTests()
+   {
+      TestNG testNG = new TestNG();
+      addUnitTests(testNG);
+      if (getConfiguration().getOutputDirectory() != null)
+      {
+         testNG.setOutputDirectory(getConfiguration().getOutputDirectory());
+      }
+      testNG.run();
+   }
+   
+   private static void addUnitTests(TestNG testNG)
+   {
+      InputStream is = TCKImpl.class.getResourceAsStream("/tck-unit-tests.xml");
+      if (is == null)
+      {
+         throw new IllegalStateException("Unable to load testng.xml");
+      }
+      List<XmlSuite> suites = new ArrayList<XmlSuite>();
+      try
+      {
+         suites.addAll(new Parser(is).parse());
+         
+      }
+      catch (ParserConfigurationException e)
+      {
+         throw new IllegalStateException("Unable to load testng.xml", e);
+      }
+      catch (SAXException e)
+      {
+         throw new IllegalStateException("Unable to load testng.xml", e);
+      }
+      catch (IOException e)
+      {
+         throw new IllegalStateException("Unable to load testng.xml", e);
+      }
+      testNG.setXmlSuites(suites);
+   }
+
+   @Override
+   public void dumpArtifacts()
+   {
+      Configuration configuration = new PropertiesBasedConfigurationImpl();
+      configuration.setStandalone(false);
+      new ArtifactGenerator(configuration).dumpArtifacts();
+   }
+
+   @Override
+   public Configuration getConfiguration()
+   {
+      return ConfigurationImpl.get();
+   }
+
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Artifact.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Artifact.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Artifact.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,36 @@
+package org.jboss.testharness.impl.packaging;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Mark this class as requiring an JSR299 artifact to be deployed for the 
+ * container. By default all classes in the current package, as well as support
+ * classes, will be deployed. The resultant artifact may not support session
+ * beans.
+ * 
+ * This test may be a unit test (in which case, if the suite is run in 
+ * standalone mode, the artifact itself won't be deployed, just the contained 
+ * classes and /META-INF/beans.xml file).
+ * 
+ * @see Classes
+ * @see IntegrationTest
+ * @see Packaging
+ * @see Resources
+ * 
+ * @author Pete Muir
+ *
+ */
+ at Documented
+ at Retention(RUNTIME)
+ at Target(TYPE)
+public @interface Artifact
+{
+   
+   boolean addCurrentPackage() default true;
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ArtifactDescriptor.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ArtifactDescriptor.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ArtifactDescriptor.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,501 @@
+package org.jboss.testharness.impl.packaging;
+
+import static org.jboss.testharness.impl.util.Reflections.loadClass;
+import static org.jboss.testharness.impl.util.Reflections.loadResourceAsStream;
+import static org.jboss.testharness.impl.util.Reflections.loadResources;
+import static org.jboss.testharness.impl.util.Strings.isEmpty;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLDecoder;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+import org.apache.log4j.Logger;
+import org.jboss.testharness.impl.util.Files;
+
+public class ArtifactDescriptor
+{
+  
+   private static final Logger log = Logger.getLogger(ArtifactScanner.class);
+   
+   /**
+    * Implementation of {@link Scanner} which can scan a {@link URLClassLoader}
+    * 
+    * @author Thomas Heute
+    * @author Gavin King
+    * @author Norman Richards
+    * @author Pete Muir
+    *
+    */
+   private static class URLPackageScanner
+   {
+      private static final Logger log = Logger.getLogger(URLPackageScanner.class);
+    
+      private final String packageName;
+      
+      private final String packageNamePath;
+      private final boolean addRecursively; 
+      
+      private final Set<String> classes = new HashSet<String>();
+      
+      public URLPackageScanner(Package pkg, boolean addRecursively)
+      {
+         this(pkg.getName(), addRecursively);
+      }
+      
+      public URLPackageScanner(String packageName, boolean addRecursively)
+      {
+         this.packageName = packageName;
+         this.packageNamePath = packageName.replace(".", "/");
+         this.addRecursively = addRecursively;
+      }
+      
+      private void scanPackage()
+      {
+         try
+         {
+            Set<String> paths = new HashSet<String>();
+            
+            for (URL url : loadResources(packageNamePath))
+            {
+               String urlPath = url.getFile();
+               urlPath = URLDecoder.decode(urlPath, "UTF-8");
+               if ( urlPath.startsWith("file:") )
+               {
+                     urlPath = urlPath.substring(5);
+               }
+               if ( urlPath.indexOf('!')>0 )
+               {
+                  urlPath = urlPath.substring(0, urlPath.indexOf('!'));
+               }
+               paths.add(urlPath);
+            }
+            handle(paths);
+         }
+         catch (IOException ioe) 
+         {
+            log.warn("could not read: " + packageName, ioe);
+         }
+      }
+      
+      private void handleArchiveByFile(File file) throws IOException
+      {
+         try
+         {
+            log.trace("archive: " + file);
+            ZipFile zip = new ZipFile(file);
+            Enumeration<? extends ZipEntry> entries = zip.entries();
+            while ( entries.hasMoreElements() )
+            {
+               ZipEntry entry = entries.nextElement();
+               String name = entry.getName();
+               if (name.startsWith(packageNamePath) && name.endsWith(".class") && (addRecursively || !name.substring(packageNamePath.length() + 1).contains("/")))
+               {
+                  String className = name.replace("/", ".").replace(".class", "");
+                  classes.add(className);
+               }
+            }
+         }
+         catch (ZipException e)
+         {
+            throw new RuntimeException("Error handling file " + file, e);
+         }
+      }
+      
+      private void handle(Set<String> paths) throws IOException
+      {
+         for ( String urlPath: paths )
+         {
+            log.trace("scanning: " + urlPath);
+            File file = new File(urlPath);
+            if ( file.isDirectory() )
+            {
+               handle(file, packageName);
+            }
+            else
+            {
+               handleArchiveByFile(file);
+            }
+         }
+      }
+      
+      private void handle(File file, String packageName)
+      {
+         for ( File child: file.listFiles() )
+         {
+            if ( !child.isDirectory() && child.getName().endsWith(".class"))
+            {
+               classes.add(packageName + "." + child.getName().substring(0, child.getName().lastIndexOf(".class")));
+            }
+            else if (child.isDirectory() && addRecursively)
+            {
+               handle(child, packageName + "." + child.getName());
+            }
+         }
+      }
+      
+      public Set<String> getClassNames()
+      {
+         scanPackage();
+         return classes;
+      }
+      
+   }
+   
+   private static class JarCreator
+   {
+      
+      private final File root;
+      
+      public JarCreator(File root)
+      {
+         this.root = root;
+      }
+      
+      public InputStream jar() throws IOException
+      {
+         ByteArrayOutputStream byteArrayOutputStream = null;
+         JarOutputStream jarOutputStream = null;
+         try
+         {
+            byteArrayOutputStream = new ByteArrayOutputStream();
+            Manifest manifest = new Manifest();
+            Attributes attributes = manifest.getMainAttributes();
+            attributes.putValue("Created-By", "JSR-299 TCK Harness");
+            attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
+            jarOutputStream = new JarOutputStream(byteArrayOutputStream, manifest);
+            jar(root, jarOutputStream);
+            jarOutputStream.close();
+            return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+         }
+         finally
+         {
+            if (jarOutputStream != null)
+            {
+               jarOutputStream.close();
+            }
+            else if (byteArrayOutputStream != null)
+            {
+               byteArrayOutputStream.close();
+            }
+         }
+      }
+      
+      private void jar(File directory, JarOutputStream jarOutputStream) throws IOException
+      {
+         File[] children = directory.listFiles(); 
+         //loop through dirList, and zip the files 
+         for (File child : children) 
+         {
+            if (child.isDirectory()) 
+            { 
+               jar(child, jarOutputStream);
+            } 
+            else
+            {
+               FileInputStream fis = new FileInputStream(child); 
+               JarEntry jarEntry = new JarEntry(child.getPath().substring(root.getPath().length() + 1).replaceAll("\\" + File.separator, "/"));  
+               jarOutputStream.putNextEntry(jarEntry);  
+               Files.copy(fis, jarOutputStream);
+               fis.close();
+            }
+         }
+      }
+      
+   }
+   
+   public static final Random random = new Random(System.currentTimeMillis());
+   
+   private final Set<Class<?>> classes;
+   private final Set<ResourceDescriptor> resources;
+   private final Set<ResourceDescriptor> libraries;
+   private final Class<?> declaringClass;
+   
+   // Cache
+   private InputStream jar;
+   private File explodedJar;
+   
+   private File classesRoot;
+   private File librariesRoot;
+   
+   public ArtifactDescriptor(Class<?> declaringClass)
+   {
+      classes = new HashSet<Class<?>>();
+      resources = new HashSet<ResourceDescriptor>();
+      this.declaringClass = declaringClass;
+      this.libraries = new HashSet<ResourceDescriptor>();
+   }
+   
+   public InputStream getJarAsStream() throws IOException
+   { 
+      if (jar == null)
+      {
+         jar = new JarCreator(getExplodedJar()).jar();
+      }
+      return jar;
+   }
+   
+   public URL getJar() throws IOException
+   {
+      InputStream is = null;
+      try
+      {
+         is = getJarAsStream();
+         File file = File.createTempFile(ArtifactDescriptor.class.getCanonicalName(), ".jar");
+         file.deleteOnExit();
+         Files.copy(is, file);
+         is.close();
+         return file.toURI().toURL();
+      }
+      finally
+      {
+         if (is != null)
+         {
+            is.close();
+         }
+      }
+   }
+   
+   public File getExplodedJar() throws IOException
+   {
+      if (explodedJar == null)
+      {
+         create();
+      }
+      return explodedJar;
+   }
+   
+   public void create() throws IOException
+   {
+      explodedJar = null;
+      jar = null;
+      
+      File root = new File(System.getProperty("java.io.tmpdir") + "/" + getClass().getName() + "." + random.nextInt());
+      root.mkdir();
+      root.deleteOnExit();
+      for (Class<?> clazz : classes)
+      {
+         copyClass(clazz, getClassesRoot(root));
+      }
+      for (ResourceDescriptor resourceDescriptor : resources)
+      {
+         copyResource(resourceDescriptor, root);
+      }
+      if (isLibrariesSupported())
+      {
+         for (ResourceDescriptor resourceDescriptor : libraries)
+         {
+            copyResource(resourceDescriptor, getLibraryRoot(root));
+         }
+      }
+      this.explodedJar = root;
+   }
+   
+   private static void copyClass(Class<?> clazz, File root) throws IOException
+   {
+      copyClass(clazz.getName(), root);
+   }
+   
+   private static void copyResource(ResourceDescriptor resourceDescriptor, File root) throws IOException
+   {
+      String directoryName;
+      String fileName;
+      if (resourceDescriptor.getName().lastIndexOf("/") > 0)
+      {
+         directoryName = resourceDescriptor.getName().substring(0, resourceDescriptor.getName().lastIndexOf("/"));
+         fileName = resourceDescriptor.getName().substring(resourceDescriptor.getName().lastIndexOf("/") + 1);
+      }
+      else
+      {
+         directoryName = "";
+         fileName = resourceDescriptor.getName();
+      }
+      if (isEmpty(fileName))
+      {
+         throw new IllegalArgumentException("Unable to determine source file name of " + resourceDescriptor);
+      }
+      File directory = makeDirectoryStructure(root, directoryName);
+      File file = new File(directory, fileName);
+      file.createNewFile();
+      file.deleteOnExit();
+      Files.copy(resourceDescriptor.getSource().openStream(), file);
+   }
+   
+   private static void copyClass(String className, File root) throws IOException
+   {
+      InputStream clazzStream = null;
+      try
+      {
+         String classFilePathName = getClassFileName(className);
+         String directoryName = classFilePathName.substring(0, classFilePathName.lastIndexOf("/"));
+         String classFileName = classFilePathName.substring(classFilePathName.lastIndexOf("/") + 1);
+         File packageDirectory = makeDirectoryStructure(root, directoryName);
+         File classFile = new File(packageDirectory, classFileName);
+         classFile.createNewFile();
+         classFile.deleteOnExit();
+         clazzStream = loadResourceAsStream(classFilePathName);
+         Files.copy(clazzStream, classFile);
+      }
+      finally
+      {
+         if (clazzStream != null)
+         {
+            clazzStream.close();
+         }
+      }
+   }
+   
+   private static File makeDirectoryStructure(File root, String directoryName)
+   {
+      for (String directory : directoryName.split("\\/"))
+      {
+         root = new File(root, directory);
+         root.mkdir();
+         root.deleteOnExit();
+      }
+      return root;
+   }
+   
+   public void writeArtifactToDisk(String outputDirectory) throws IOException
+   {
+      writeArtifactToDisk(outputDirectory, getDefaultName());
+   }
+   
+   public void writeArtifactToDisk(String outputDirectory, String fileName) throws IOException
+   {
+      OutputStream os = null;
+      InputStream jar = null;
+      try
+      {
+         File file = new File(outputDirectory, fileName);
+         file.createNewFile();
+         os = new BufferedOutputStream(new FileOutputStream(file));
+         jar = getJarAsStream();
+         Files.copy(jar, os);
+      }
+      finally
+      {
+         if (os != null)
+         {
+            os.close();
+         }
+         if (jar != null)
+         {
+            jar.close();
+         }
+      }
+   }
+   
+   public String getDefaultName()
+   {
+      return declaringClass.getName() + getExtension();
+   }
+   
+   private static String getClassFileName(String className)
+   {
+      return className.replace('.', '/') + ".class";
+   }
+   
+   public Set<Class<?>> getClasses()
+   {
+      return classes;
+   }
+
+   public Set<ResourceDescriptor> getResources()
+   {
+      return resources;
+   }
+   
+   public void addPackage(Package pkg)
+   {
+      addPackage(pkg.getName(), false);
+   }
+   
+   public void addPackage(String packageName, boolean addRecursively)
+   {
+      URLPackageScanner packageScanner = new URLPackageScanner(packageName, addRecursively);
+      for (String className : packageScanner.getClassNames())
+      {
+         Class<?> clazz = loadClass(className);
+         if (clazz == null)
+         {
+            System.out.println("Class null: " + className);
+         }
+         getClasses().add(clazz);
+      }
+   }
+   
+   public File getClassesRoot(File archiveRoot)
+   {
+      if (classesRoot == null)
+      {
+         classesRoot = makeDirectoryStructure(archiveRoot, getClassesRoot());
+      }
+      return classesRoot;
+   }
+   
+   public String getClassesRoot()
+   {
+      return "/";
+   }
+   
+   @Override
+   public String toString()
+   {
+      return "Declared by: " + declaringClass.getName() + " Classes: " + classes + " Resources: " + resources;
+   }
+   
+   public Class<?> getDeclaringClass()
+   {
+      return declaringClass;
+   }
+   
+   public String getExtension()
+   {
+      return ".jar";
+   }
+   
+   public Set<ResourceDescriptor> getLibraries()
+   {
+      return libraries;
+   }
+   
+   public File getLibraryRoot(File archiveRoot)
+   {
+      if (librariesRoot == null)
+      {
+         librariesRoot = makeDirectoryStructure(archiveRoot, getLibrariesRoot());
+      }
+      return librariesRoot;
+   }
+   
+   protected String getLibrariesRoot()
+   {
+      return "/";
+   }
+
+   public boolean isLibrariesSupported()
+   {
+      return false;
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ArtifactGenerator.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ArtifactGenerator.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ArtifactGenerator.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,278 @@
+package org.jboss.testharness.impl.packaging;
+
+import static org.jboss.testharness.impl.packaging.PackagingType.EAR;
+import static org.jboss.testharness.impl.packaging.PackagingType.WAR;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.jboss.testharness.AbstractTest;
+import org.jboss.testharness.api.Configuration;
+import org.jboss.testharness.impl.packaging.ear.EarArtifactDescriptor;
+import org.jboss.testharness.impl.packaging.jsr299.BeansXml;
+import org.jboss.testharness.impl.packaging.jsr299.TCKArtifactDescriptor;
+import org.jboss.testharness.impl.packaging.war.WarArtifactDescriptor;
+
+public class ArtifactGenerator
+{
+   
+   private static class ArtifactProcessor
+   {
+      
+      private static final Logger log = Logger.getLogger(ArtifactProcessor.class);
+      
+      private final boolean unit;
+      private final boolean runLocally;
+      private final boolean addDeclaringPackage;
+      private final String beansXml;
+      private final PackagingType packagingType;
+      private final Collection<ResourceDescriptor> resources;
+      private final Collection<Class<?>> classes;
+      private final Class<? extends Throwable> expectedDeploymentException;
+      private final Set<ResourceDescriptor> extraLibraries;
+      
+      
+      private final Class<?> declaringClass;
+      private final boolean standalone;
+
+      public ArtifactProcessor(Class<?> declaringClass, boolean standalone, String extraLibrariesDirectory)
+      {
+         this.standalone = standalone;
+         this.declaringClass = declaringClass;
+         
+         if (declaringClass.isAnnotationPresent(Artifact.class))
+         {
+            this.addDeclaringPackage = declaringClass.getAnnotation(Artifact.class).addCurrentPackage();
+         }
+         else
+         {
+            throw new IllegalStateException("Unable to find @Artifact on " + declaringClass);
+         }
+         
+         if (declaringClass.isAnnotationPresent(BeansXml.class))
+         {
+            this.beansXml = asAbsolutePath(declaringClass.getAnnotation(BeansXml.class).value());
+         }
+         else
+         {
+            this.beansXml = null;
+         }
+         
+         if (declaringClass.isAnnotationPresent(Packaging.class))
+         {
+            this.packagingType = declaringClass.getAnnotation(Packaging.class).value();
+         }
+         else
+         {
+            this.packagingType = WAR;
+         }
+         
+         if (declaringClass.isAnnotationPresent(IntegrationTest.class))
+         {
+            this.unit = false;
+            this.runLocally = declaringClass.getAnnotation(IntegrationTest.class).runLocally(); 
+         }
+         else
+         {
+            this.unit = true;
+            this.runLocally = false;
+         }
+         
+         if (declaringClass.isAnnotationPresent(Resources.class))
+         {
+            this.resources = asResourceDescriptors(declaringClass.getAnnotation(Resources.class).value());
+         }
+         else
+         {
+            this.resources = Collections.emptyList();
+         }
+         
+         if (declaringClass.isAnnotationPresent(Classes.class))
+         {
+            this.classes = Arrays.asList(declaringClass.getAnnotation(Classes.class).value());
+         }
+         else
+         {
+            this.classes = Collections.emptyList();
+         }
+         if (declaringClass.isAnnotationPresent(ExpectedDeploymentException.class))
+         {
+            this.expectedDeploymentException = declaringClass.getAnnotation(ExpectedDeploymentException.class).value();
+         }
+         else
+         {
+            this.expectedDeploymentException = null;
+         }
+         if (extraLibrariesDirectory != null)
+         {
+            File directory = new File(extraLibrariesDirectory);
+            this.extraLibraries = new HashSet<ResourceDescriptor>();
+            if (directory.isDirectory())
+            {
+               for (File file : directory.listFiles(new FilenameFilter()
+                  {
+                     
+                     public boolean accept(File dir, String name)
+                     {
+                        return name.endsWith(".jar");
+                     }
+                     
+                  }))
+               {
+                  try
+                  {
+                     this.extraLibraries.add(new ResourceDescriptor(file.getName(), file.toURI().toURL()));
+                  }
+                  catch (IOException e)
+                  {
+                     log.warn("Unable to load extra library", e);
+                  }
+               }
+            }
+         }
+         else
+         {
+            this.extraLibraries = Collections.emptySet();
+         }
+      }
+      
+      public TCKArtifactDescriptor createArtifact()
+      {
+         final TCKArtifactDescriptor artifact = newArtifact(packagingType, declaringClass, beansXml, standalone, addDeclaringPackage);
+         artifact.setUnit(unit);
+         artifact.setRunLocally(runLocally);
+         artifact.setExpectedDeploymentException(expectedDeploymentException);
+         artifact.getClasses().addAll(classes);
+         // Annoying hack
+         artifact.getResources().removeAll(resources);
+         artifact.getResources().addAll(resources);
+         artifact.getLibraries().addAll(extraLibraries);
+         return artifact;
+      }
+      
+      private Collection<ResourceDescriptor> asResourceDescriptors(Resource[] resources)
+      {
+         List<ResourceDescriptor> resourceDescriptors = new ArrayList<ResourceDescriptor>();
+         for (Resource resource : resources)
+         {
+            resourceDescriptors.add(new ResourceDescriptor(resource.destination(), asAbsolutePath(resource.source())));
+         }
+         return resourceDescriptors;
+      }
+      
+      private String asAbsolutePath(String path)
+      {
+         if (path.startsWith("/"))
+         {
+            return path.substring(1);
+         }
+         else
+         {
+            return declaringClass.getPackage().getName().replace(".", "/") + "/" + path;
+         }
+      }
+      
+      private static TCKArtifactDescriptor newArtifact(PackagingType packagingType, Class<?> declaringClass, String beansXml, boolean standalone, boolean addDeclaringPackage)
+      {
+         TCKArtifactDescriptor artifact;
+         if (!standalone && packagingType.equals(WAR))
+         {
+               artifact = new WarArtifactDescriptor(declaringClass, beansXml);
+         } 
+         else if (!standalone && packagingType.equals(EAR))
+         {
+            artifact = new EarArtifactDescriptor(declaringClass, beansXml);
+         }
+         else
+         {
+            artifact = new TCKArtifactDescriptor(declaringClass, beansXml);
+         }
+         
+         if (addDeclaringPackage)
+         {
+            artifact.addPackage(declaringClass.getPackage());
+         }
+         return artifact;
+      }
+      
+      public boolean isUnit()
+      {
+         return unit;
+      };
+      
+   }
+   
+   private static final Logger log = Logger.getLogger(ArtifactGenerator.class);
+   
+   private final Configuration configuration;
+   
+   public ArtifactGenerator(Configuration configuration)
+   {
+      if (configuration == null)
+      {
+         throw new IllegalArgumentException("configuration must not be null");
+      }
+      this.configuration = configuration;
+   }
+
+   public List<ArtifactDescriptor> createArtifacts(String packageName)
+   {
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.addAll(new ArtifactScanner(packageName, null).getClasses());
+      List<ArtifactDescriptor> artifacts = new ArrayList<ArtifactDescriptor>();
+      for (Class<?> clazz : classes)
+      {
+         artifacts.add(createArtifact(clazz));
+      }
+      return artifacts;
+   }
+   
+   public void dumpArtifacts() 
+   {
+      List<ArtifactDescriptor> artifacts = createArtifacts(AbstractTest.class.getPackage().getName());
+      File file = new File(configuration.getOutputDirectory());
+      if (!file.exists())
+      {
+         file.mkdirs();
+      }
+      else if (file.isFile())
+      {
+         throw new IllegalStateException("Cannot use debug directory " + configuration.getOutputDirectory() + ", it already exists");
+      }
+      log.info("Writing artifacts to " + configuration.getOutputDirectory());
+      for (ArtifactDescriptor artifact : artifacts)
+      {
+         try
+         {
+            artifact.writeArtifactToDisk(configuration.getOutputDirectory());
+            log.info("Written artifact to disk " + artifact);
+         }
+         catch (IOException e)
+         {
+            log.warn("Error writing artifact to disk " + artifact, e);
+         }
+      }
+   }
+
+   public TCKArtifactDescriptor createArtifact(Class<?> declaringClass)
+   {
+      if (declaringClass.isAnnotationPresent(Artifact.class))
+      {
+         return new ArtifactProcessor(declaringClass, configuration.isStandalone(), configuration.getLibraryDirectory()).createArtifact();
+      }
+      else
+      {
+         return null;
+      }
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ArtifactScanner.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ArtifactScanner.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ArtifactScanner.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,148 @@
+/**
+ * 
+ */
+package org.jboss.testharness.impl.packaging;
+
+import static org.jboss.testharness.impl.util.Reflections.loadResources;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+import org.apache.log4j.Logger;
+import org.jboss.testharness.impl.util.Reflections;
+
+public class ArtifactScanner
+{
+   private static final Logger log = Logger.getLogger(ArtifactScanner.class);
+
+   private final String packageName;
+   private final String packageNameAsPath;
+   private final Class<? extends Annotation> annotationType;
+   
+   private final Set<Class<?>> classes = new HashSet<Class<?>>();
+   
+   public ArtifactScanner(String packageName, Class<? extends Annotation> annotation)
+   {
+      this.packageName = packageName;
+      this.packageNameAsPath = packageName.replace(".", "/");
+      this.annotationType = annotation;
+   }
+   
+   private void scan()
+   {
+      try
+      {
+         Set<String> paths = new HashSet<String>();
+         
+         for (URL url : loadResources(packageNameAsPath))
+         {
+            String urlPath = url.getFile();
+            urlPath = URLDecoder.decode(urlPath, "UTF-8");
+            if ( urlPath.startsWith("file:") )
+            {
+                  urlPath = urlPath.substring(5);
+            }
+            if ( urlPath.indexOf('!')>0 )
+            {
+               urlPath = urlPath.substring(0, urlPath.indexOf('!'));
+            }
+            paths.add(urlPath);
+         }
+         handle(paths);
+      }
+      catch (IOException ioe) 
+      {
+         log.warn("could not read: " + this.packageName, ioe);
+      }
+   }
+   
+   private void handle(Set<String> paths) throws IOException
+   {
+      for ( String urlPath: paths )
+      {
+         log.trace("scanning: " + urlPath);
+         handle(new File(urlPath), packageName.substring(0, packageName.lastIndexOf(".")));
+         
+      }
+   }
+   
+   private void handleArchiveByFile(File file) throws IOException
+   {
+      try
+      {
+         log.trace("archive: " + file);
+         ZipFile zip = new ZipFile(file);
+         Enumeration<? extends ZipEntry> entries = zip.entries();
+         while ( entries.hasMoreElements() )
+         {
+            ZipEntry entry = entries.nextElement();
+            String name = entry.getName();
+            if (name.startsWith(packageNameAsPath) && name.endsWith(".class"))
+            {
+               addClass(name.replace(".class", "").replace("/", "."));
+            }
+         }
+      }
+      catch (ZipException e)
+      {
+         throw new RuntimeException("Error handling file " + file, e);
+      }
+   }
+   
+   private void handle(File file, String packageName) throws IOException
+   {
+      if ( file.isDirectory() )
+      {
+         packageName = packageName + "." + file.getName();
+         for ( File child: file.listFiles() )
+         {
+            handle(child, packageName);
+         }
+      }
+      else if (file.getName().endsWith(".class") && ! file.getName().contains("$"))
+      {
+         addClass(packageName + "." + file.getName().replace(".class", ""));
+         
+      }
+      else if (file.getName().endsWith(".jar"))
+      {
+         handleArchiveByFile(file);
+      }
+   }
+   
+   private void addClass(String className)
+   {
+      Class<?> clazz = Reflections.loadClass(className);
+      if (clazz != null && clazz.isAnnotationPresent(Artifact.class))
+      {
+         if (annotationType != null && clazz.isAnnotationPresent(annotationType))
+         {
+            classes.add(clazz);
+         }
+         else
+         {
+            classes.add(clazz);
+         }
+      }
+      else if (clazz == null)
+      {
+         log.warn("Unable to load class " + className);
+      }
+   }
+   
+   public Set<Class<?>> getClasses()
+   {
+      scan();
+      return classes;
+   }
+   
+}
\ No newline at end of file

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Classes.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Classes.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Classes.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,27 @@
+package org.jboss.testharness.impl.packaging;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Add classes to the deployed artifact
+ * 
+ * @see Artifact
+ * @see Resources
+ * 
+ * @author Pete Muir
+ *
+ */
+ at Documented
+ at Retention(RUNTIME)
+ at Target(TYPE)
+public @interface Classes
+{
+   
+   Class<?>[] value();
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ExpectedDeploymentException.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ExpectedDeploymentException.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ExpectedDeploymentException.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,25 @@
+package org.jboss.testharness.impl.packaging;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Mark this artifact as expecting to fail a deployment with the given exception
+ * or some subtype of it.
+ * 
+ * @author Pete Muir
+ *
+ */
+ at Documented
+ at Retention(RUNTIME)
+ at Target(TYPE)
+public @interface ExpectedDeploymentException
+{
+   
+   Class<? extends Throwable> value();
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/IntegrationTest.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/IntegrationTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/IntegrationTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,26 @@
+package org.jboss.testharness.impl.packaging;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Mark this test as an integration test, always requiring running in a 
+ * container.
+ * 
+ * @see Artifact
+ * @see IntegrationTest
+ * 
+ * @author Pete Muir
+ *
+ */
+ at Retention(RUNTIME)
+ at Target(TYPE)
+public @interface IntegrationTest
+{
+   
+   boolean runLocally() default false;
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Packaging.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Packaging.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Packaging.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,29 @@
+package org.jboss.testharness.impl.packaging;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.jboss.testharness.impl.packaging.PackagingType.WAR;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Mark this test as requiring specific packaging when deployed to a container
+ * for intgration testing.
+ * 
+ * @see IntegrationTest
+ * @see Artifact
+ * 
+ * @author Pete Muir
+ *
+ */
+ at Documented
+ at Retention(RUNTIME)
+ at Target(TYPE)
+public @interface Packaging
+{
+   
+   PackagingType value() default WAR;
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/PackagingType.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/PackagingType.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/PackagingType.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,8 @@
+package org.jboss.testharness.impl.packaging;
+
+public enum PackagingType
+{
+   
+   EAR, WAR
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Resource.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Resource.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Resource.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,40 @@
+package org.jboss.testharness.impl.packaging;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import org.jboss.testharness.impl.packaging.jsr299.BeansXml;
+
+/**
+ * Specify an additional resource to be added to the artifact.
+ * 
+ * @see Resources
+ * @see BeansXml
+ * 
+ * @author Pete Muir
+ *
+ */
+ at Documented
+ at Retention(RUNTIME)
+ at Target(TYPE)
+public @interface Resource
+{
+   
+   /**
+    * Location, relative to the current package, or to the current archive
+    * to find the resource file
+    * 
+    */
+   String source();
+   
+   /**
+    * Destination for the resource file within the generated artifact
+    * 
+    */
+   String destination();
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ResourceDescriptor.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ResourceDescriptor.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ResourceDescriptor.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,83 @@
+package org.jboss.testharness.impl.packaging;
+
+import static org.jboss.testharness.impl.util.Reflections.loadResource;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.jboss.testharness.impl.util.Files;
+
+public class ResourceDescriptor
+{
+   
+   private final String name;
+   private final URL source;
+
+   public ResourceDescriptor(String name, InputStream source) throws IOException
+   {
+      this.name = name;
+      File file = File.createTempFile(ResourceDescriptor.class.getName(), null);
+      file.deleteOnExit();
+      Files.copy(source, file);
+      this.source = file.toURI().toURL(); 
+   }
+   
+   public ResourceDescriptor(String name, URL source)
+   {
+      this.name = name;
+      this.source = source;
+   }
+   
+   public ResourceDescriptor(String name, String source)
+   {
+      this.name = name;
+      if (name == null)
+      {
+         throw new IllegalArgumentException("Unable to have a null resource");
+      }
+      this.source = loadResource(source);
+      if (this.source == null)
+      {
+         throw new IllegalArgumentException("Unable to load file for " + source);
+      }
+   }
+   
+   public String getName()
+   {
+      return name;
+   }
+   
+   public URL getSource()
+   {
+      return source;
+   }
+   
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (obj instanceof ResourceDescriptor)
+      {
+         ResourceDescriptor that = (ResourceDescriptor) obj;
+         return this.getName().equals(that.getName());
+      }
+      else
+      {
+         return false;
+      }
+   }
+   
+   @Override
+   public int hashCode()
+   {
+      return name.hashCode();
+   }
+   
+   @Override
+   public String toString()
+   {
+      return name + " (" + source.toString() + ")";
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Resources.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Resources.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/Resources.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,26 @@
+package org.jboss.testharness.impl.packaging;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Specify additional resources for an artifact
+ * 
+ * @see Resource
+ * @see Classes
+ * @see Artifact
+ * 
+ * @author Pete Muir
+ *
+ */
+ at Retention(RUNTIME)
+ at Target(TYPE)
+public @interface Resources
+{
+   
+   Resource[] value();
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ear/EarArtifactDescriptor.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ear/EarArtifactDescriptor.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ear/EarArtifactDescriptor.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,164 @@
+package org.jboss.testharness.impl.packaging.ear;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.jboss.testharness.impl.packaging.ResourceDescriptor;
+import org.jboss.testharness.impl.packaging.jsr299.TCKArtifactDescriptor;
+import org.jboss.testharness.impl.packaging.war.WarArtifactDescriptor;
+
+public class EarArtifactDescriptor extends TCKArtifactDescriptor
+{
+   
+   private static final Logger log = Logger.getLogger(EarArtifactDescriptor.class);
+   
+   public static final String APPLICATION_XML_DESTINATION = "META-INF/application.xml";
+   
+   private final EjbJarArtifactDescriptor ejbJar;
+   private final WarArtifactDescriptor war;
+   
+   public EarArtifactDescriptor(Class<?> declaringClass, String beansXmlSourceFileName)
+   {
+      super(declaringClass, null);
+      this.ejbJar = new EjbJarArtifactDescriptor(declaringClass, beansXmlSourceFileName);
+      this.war = new WarArtifactDescriptor(declaringClass, null)
+      {
+         
+         @Override
+         protected boolean isAddBeansXml()
+         {
+            return false;
+         }
+         
+         @Override
+         public boolean isLibrariesSupported()
+         {
+            return false;
+         }
+         
+      };
+      InputStream applicationXml = null;
+      try
+      {
+         applicationXml = getApplicationXml(declaringClass);
+         getResources().add(new ResourceDescriptor(APPLICATION_XML_DESTINATION, applicationXml));
+      }
+      catch (IOException e)
+      {
+         log.warn("Error generating ear", e);
+      }
+      finally
+      {
+         if (applicationXml != null)
+         {
+            try
+            {
+               applicationXml.close();
+            }
+            catch (IOException e1)
+            {
+               log.error("Error generating ear", e1);
+            }
+         }
+      }
+   }
+   
+   @Override
+   public Set<Class<?>> getClasses()
+   {
+      return getEjbJar().getClasses();
+   }
+   
+   public EjbJarArtifactDescriptor getEjbJar()
+   {
+      return ejbJar;
+   }
+   
+   public WarArtifactDescriptor getWar()
+   {
+      return war;
+   }
+   
+   @Override
+   public String toString()
+   {
+      return "ear, " + super.toString();
+   }
+   
+   @Override
+   public String getExtension()
+   {
+      return ".ear";
+   }
+   
+   @Override
+   public boolean isLibrariesSupported()
+   {
+      return true;
+   }
+   
+   @Override
+   protected String getLibrariesRoot()
+   {
+      return "lib";
+   }
+   
+   @Override
+   protected boolean isAddBeansXml()
+   {
+      return false;
+   }
+   
+   @Override
+   public void create() throws IOException
+   {
+      for (ResourceDescriptor resource : new HashSet<ResourceDescriptor>(getResources()))
+      {
+         if (resource.getName().startsWith("war"))
+         {
+            getResources().remove(resource);
+            war.getResources().add(new ResourceDescriptor(resource.getName().substring(3), resource.getSource()));
+         }
+      }
+      getResources().add(new ResourceDescriptor(war.getDefaultName(), war.getJar()));
+      getResources().add(new ResourceDescriptor(ejbJar.getDefaultName(), ejbJar.getJar()));
+      super.create();
+   }
+   
+   private static InputStream getApplicationXml(Class<?> declaringClass) throws IOException
+   {
+      ByteArrayOutputStream os = new ByteArrayOutputStream();
+      try
+      {
+         Writer writer = new PrintWriter(os);
+         writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+         writer.write("<application xmlns=\"http://java.sun.com/xml/ns/javaee\" \n" + 
+                   "\t\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n" +
+                   "\t\txsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd\" \n" +
+                   "\t\tversion=\"5\">\n\n");
+         writer.write("\t<display-name>JSR-99 TCK: " + declaringClass.getName() + "</display-name>\n\n");
+         writer.write("\t<module>\n" +
+              "\t\t<web>\n" +
+                  "\t\t\t<web-uri>" + declaringClass.getName() +".war</web-uri>\n" + 
+                  "\t\t\t<context-root>/" + declaringClass.getName() + "</context-root>\n" +
+              "\t\t</web>\n" +
+          "\t</module>\n\n");
+         writer.write("\t<module>\n" +
+                   "\t\t<ejb>" + declaringClass.getName() +".jar</ejb>\n" + 
+           "\t</module>\n\n");
+         writer.write("</application>\n");
+         writer.flush();
+         return new ByteArrayInputStream(os.toByteArray());
+      }
+      finally
+      {
+         os.close();
+      }
+   }
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ear/EjbJarArtifactDescriptor.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ear/EjbJarArtifactDescriptor.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/ear/EjbJarArtifactDescriptor.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,39 @@
+package org.jboss.testharness.impl.packaging.ear;
+import static org.jboss.testharness.impl.util.Reflections.loadResource;
+
+import java.net.URL;
+
+import org.jboss.testharness.impl.packaging.ResourceDescriptor;
+import org.jboss.testharness.impl.packaging.jsr299.JSR299ArtifactDescriptor;
+
+public class EjbJarArtifactDescriptor extends JSR299ArtifactDescriptor
+{
+   
+   public static final String EJB_JAR_XML_DESTINATION = "META-INF/ejb-jar.xml";
+   public static final String STANDARD_EJB_JAR_XML_FILE_NAME = "org/jboss/testharness/impl/packaging/ear/ejb-jar.xml";
+   public static final String CUSTOM_EJB_JAR_XML_FILE_NAME = "org/jboss/testharness/impl/packaging/ear/custom-ejb-jar.xml";
+   
+   public EjbJarArtifactDescriptor(Class<?> declaringClass, String beansXmlSourceFileName)
+   {
+      super(declaringClass, beansXmlSourceFileName);
+      URL ejbJarXml = loadResource(CUSTOM_EJB_JAR_XML_FILE_NAME);
+      if (ejbJarXml == null)
+      {
+         ejbJarXml = loadResource(STANDARD_EJB_JAR_XML_FILE_NAME);
+      }
+      getResources().add(new ResourceDescriptor(EJB_JAR_XML_DESTINATION, ejbJarXml));
+   }
+   
+   @Override
+   public String toString()
+   {
+      return "ejb jar, " + super.toString();
+   }
+   
+   @Override
+   public boolean isLibrariesSupported()
+   {
+      return false;
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/jsr299/BeansXml.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/jsr299/BeansXml.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/jsr299/BeansXml.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,33 @@
+package org.jboss.testharness.impl.packaging.jsr299;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import org.jboss.testharness.impl.packaging.Resource;
+
+/**
+ * Override the default (empty) META-INF/beans.xml
+ * 
+ * @see Resource
+ * 
+ * @author Pete Muir
+ *
+ */
+ at Documented
+ at Retention(RUNTIME)
+ at Target(TYPE)
+public @interface BeansXml
+{
+   
+   /**
+    * Location of the overriding file, relative to the current location or the
+    * root this classpath
+    * 
+    */
+   String value();
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/jsr299/JSR299ArtifactDescriptor.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/jsr299/JSR299ArtifactDescriptor.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/jsr299/JSR299ArtifactDescriptor.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,49 @@
+package org.jboss.testharness.impl.packaging.jsr299;
+
+import static org.jboss.testharness.impl.util.Strings.isEmpty;
+
+import org.jboss.testharness.impl.packaging.ArtifactDescriptor;
+import org.jboss.testharness.impl.packaging.ResourceDescriptor;
+
+public class JSR299ArtifactDescriptor extends ArtifactDescriptor
+{
+   
+   public static final String BEANS_XML_DESTINATION = "META-INF/beans.xml";
+   public static final String STANDARD_BEANS_XML_FILE_NAME = "org/jboss/testharness/impl/packaging/jsr299/default/beans.xml";
+   
+   private final ResourceDescriptor beansXml;
+   
+   public JSR299ArtifactDescriptor(Class<?> declaringClass, String beansXmlSourceFileName)
+   {
+      super(declaringClass);
+      if (!isAddBeansXml())
+      {
+         this.beansXml = null;
+      }
+      else
+      {
+         if (isEmpty(beansXmlSourceFileName))
+         {
+            beansXmlSourceFileName = STANDARD_BEANS_XML_FILE_NAME;
+         }
+         this.beansXml = new ResourceDescriptor(getBeansDestination(), beansXmlSourceFileName);
+         getResources().add(beansXml);
+      }
+   }
+   
+   public String getBeansDestination()
+   {
+      return BEANS_XML_DESTINATION; 
+   }
+   
+   public ResourceDescriptor getBeansXml()
+   {
+      return beansXml;
+   }
+   
+   protected boolean isAddBeansXml()
+   {
+      return true;
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/jsr299/TCKArtifactDescriptor.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/jsr299/TCKArtifactDescriptor.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/jsr299/TCKArtifactDescriptor.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,126 @@
+package org.jboss.testharness.impl.packaging.jsr299;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.Writer;
+
+import org.apache.log4j.Logger;
+import org.jboss.testharness.AbstractTest;
+import org.jboss.testharness.impl.packaging.ArtifactDescriptor;
+import org.jboss.testharness.impl.packaging.ResourceDescriptor;
+import org.jboss.testharness.impl.util.DeploymentProperties;
+
+public class TCKArtifactDescriptor extends JSR299ArtifactDescriptor
+{
+   
+   private static ResourceDescriptor getTckSupportJar()
+   {
+         ArtifactDescriptor descriptor = new ArtifactDescriptor(TCKArtifactDescriptor.class);
+         descriptor.addPackage(AbstractTest.class.getPackage());
+         descriptor.addPackage("org.jboss.testharness.impl", true);
+         descriptor.addPackage("org.jboss.testharness.runner", true);
+         if (descriptor.getClasses().size() == 0)
+         {
+            throw new AssertionError("Error building tck-support.jar");
+         }
+         try
+         {
+            return new ResourceDescriptor("tck-support.jar", descriptor.getJar());
+         }
+         catch (IOException e)
+         {
+            throw new RuntimeException("Error building TCK support Jar", e);
+         }
+   }
+   
+   private static final Logger log = Logger.getLogger(TCKArtifactDescriptor.class);
+   
+   private boolean unit;
+   private boolean runLocally;
+   private Class<? extends Throwable> expectedDeploymentException;
+   
+   public TCKArtifactDescriptor(Class<?> declaringClass, String beansXmlSourceFileName)
+   {
+      super(declaringClass, beansXmlSourceFileName);
+      if (isLibrariesSupported())
+      {
+         getLibraries().add(new ResourceDescriptor("testng.jar", "/lib/testng-jdk15.jar"));
+         getLibraries().add(new ResourceDescriptor("jboss-test-harness-api.jar", "/lib/jboss-test-harness-api.jar"));
+         getLibraries().add(getTckSupportJar());
+         InputStream deploymentProperties = null;
+         try
+         {
+            deploymentProperties = getDeploymentProperties(declaringClass);
+            getResources().add(new ResourceDescriptor(getClassesRoot() + DeploymentProperties.RESOURCE_BUNDLE, deploymentProperties));
+         }
+         catch (IOException e)
+         {
+            log.warn("Error generating deployment properties", e);
+         }
+         finally
+         {
+            if (deploymentProperties != null)
+            {
+               try
+               {
+                  deploymentProperties.close();
+               }
+               catch (IOException e)
+               {
+                  log.error("Error generating deployment properties", e);
+               }
+            }
+         }
+      }
+   }
+   
+   private static InputStream getDeploymentProperties(Class<?> declaringClass) throws IOException
+   {
+      ByteArrayOutputStream os = new ByteArrayOutputStream();
+      try
+      {
+         Writer writer = new PrintWriter(os);
+         writer.write("className=" + declaringClass.getName());
+         writer.flush();
+         return new ByteArrayInputStream(os.toByteArray());
+      }
+      finally
+      {
+         os.close();
+      }
+   }
+   
+   public boolean isUnit()
+   {
+      return unit;
+   }
+   
+   public void setUnit(boolean unit)
+   {
+      this.unit = unit;
+   }
+   
+   public Class<? extends Throwable> getExpectedDeploymentException()
+   {
+      return expectedDeploymentException;
+   }
+   
+   public void setExpectedDeploymentException(Class<? extends Throwable> expectedDeploymentException)
+   {
+      this.expectedDeploymentException = expectedDeploymentException;
+   }
+   
+   public boolean isRunLocally()
+   {
+      return runLocally;
+   }
+   
+   public void setRunLocally(boolean runLocally)
+   {
+      this.runLocally = runLocally;
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/war/WarArtifactDescriptor.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/war/WarArtifactDescriptor.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/packaging/war/WarArtifactDescriptor.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,62 @@
+package org.jboss.testharness.impl.packaging.war;
+import static org.jboss.testharness.impl.util.Reflections.loadResource;
+
+import java.net.URL;
+
+import org.jboss.testharness.impl.packaging.ResourceDescriptor;
+import org.jboss.testharness.impl.packaging.jsr299.TCKArtifactDescriptor;
+
+public class WarArtifactDescriptor extends TCKArtifactDescriptor
+{
+   
+   public static final String WEB_XML_DESTINATION = "WEB-INF/web.xml";
+   public static final String STANDARD_WEB_XML_FILE_NAME = "org/jboss/testharness/impl/packaging/war/web.xml";
+   public static final String CUSTOM_WEB_XML_FILE_NAME = "org/jboss/testharness/impl/packaging/war/custom-web.xml";
+   
+   public WarArtifactDescriptor(Class<?> declaringClass, String beansXmlSourceFileName)
+   {
+      super(declaringClass, beansXmlSourceFileName);
+      URL webXml = loadResource(CUSTOM_WEB_XML_FILE_NAME);
+      if (webXml == null)
+      {
+         webXml = loadResource(STANDARD_WEB_XML_FILE_NAME);
+      }
+      getResources().add(new ResourceDescriptor(WEB_XML_DESTINATION, webXml));
+   }
+   
+   @Override
+   public String getClassesRoot()
+   {
+      return "WEB-INF/classes/";
+   }
+   
+   @Override
+   public String toString()
+   {
+      return "war, " + super.toString();
+   }
+   
+   @Override
+   public String getExtension()
+   {
+      return ".war";
+   }
+   
+   @Override
+   public boolean isLibrariesSupported()
+   {
+      return true;
+   }
+   
+   @Override
+   protected String getLibrariesRoot()
+   {
+      return "WEB-INF/lib";
+   }
+   
+   @Override
+   public String getBeansDestination()
+   {
+      return "WEB-INF/beans.xml";
+   }
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/BufferedListener.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/BufferedListener.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/BufferedListener.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,78 @@
+package org.jboss.testharness.impl.runner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.testng.ITestContext;
+import org.testng.ITestListener;
+import org.testng.ITestResult;
+
+public class BufferedListener implements ITestListener
+{
+   
+   private ITestContext context;
+   
+   
+   public BufferedListener()
+   {
+   }
+   
+   public void onFinish(ITestContext context)
+   {
+      this.context = context;
+   }
+   
+   public void onStart(ITestContext context)
+   {
+      // No-op
+   }
+   
+   public void onTestFailedButWithinSuccessPercentage(ITestResult result)
+   {
+      // No-op
+   }
+   
+   public void onTestFailure(ITestResult result)
+   {
+      // No-op
+   }
+   
+   public void onTestSkipped(ITestResult result)
+   {
+      // No-op
+   }
+   
+   public void onTestStart(ITestResult result)
+   {
+      // No-op
+   }
+   
+   public void onTestSuccess(ITestResult result)
+   {
+      // No-op
+   }
+   
+   public ITestContext getContext()
+   {
+      return context;
+   }
+   
+   public List<ITestResult> getTestResults()
+   {
+      List<ITestResult> results = new ArrayList<ITestResult>();
+      results.addAll(context.getFailedTests().getAllResults());
+      results.addAll(context.getPassedTests().getAllResults());
+      results.addAll(context.getSkippedTests().getAllResults());
+      return results;
+   }
+   
+   public List<ITestResult> getConfigurationResults()
+   {
+      List<ITestResult> results = new ArrayList<ITestResult>();
+      results.addAll(context.getFailedConfigurations().getAllResults());
+      results.addAll(context.getPassedConfigurations().getAllResults());
+      results.addAll(context.getSkippedConfigurations().getAllResults());
+      return results;
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/TestResultImpl.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/TestResultImpl.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/TestResultImpl.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,55 @@
+package org.jboss.testharness.impl.runner;
+
+import java.io.Serializable;
+
+import org.jboss.testharness.api.TestResult;
+import org.testng.ITestResult;
+
+public class TestResultImpl implements Serializable, TestResult
+{
+   
+   private static final long serialVersionUID = -6608901483105666644L;
+   
+   private Throwable throwable;
+   private Status status;
+   
+   
+   
+   public TestResultImpl(Status status, Throwable throwable)
+   {
+      super();
+      this.throwable = throwable;
+      this.status = status;
+   }
+
+   public Status getStatus()
+   {
+      return status;
+   }
+   
+   public Throwable getThrowable()
+   {
+      return throwable;
+   }
+   
+   public static TestResult of(ITestResult testNGResult)
+   {
+      if (testNGResult.getStatus() == 1)
+      {
+         return new TestResultImpl(Status.PASSED, null);
+      }
+      else if (testNGResult.getStatus() == 2)
+      {
+         return new TestResultImpl(Status.FAILED, testNGResult.getThrowable());
+      }
+      else if (testNGResult.getStatus() == 3)
+      {
+         return new TestResultImpl(Status.SKIPPED, testNGResult.getThrowable());
+      }
+      else
+      {
+         return null;
+      }
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/TestRunner.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/TestRunner.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/TestRunner.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,104 @@
+package org.jboss.testharness.impl.runner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.testharness.AbstractTest;
+import org.jboss.testharness.impl.testng.RemoveExpectedExceptionsAnnotationTransformer;
+import org.jboss.testharness.impl.util.DeploymentProperties;
+import org.testng.ITestContext;
+import org.testng.ITestResult;
+import org.testng.TestNG;
+import org.testng.xml.XmlClass;
+import org.testng.xml.XmlSuite;
+import org.testng.xml.XmlTest;
+
+public class TestRunner
+{
+   
+   private List<String> classNames;
+   private List<String> methodNames;
+   private ITestContext context;
+   private List<ITestResult> testResults;
+   private List<ITestResult> configurationResults;
+   
+   public TestRunner()
+   {   
+      methodNames = new ArrayList<String>();
+      classNames = new ArrayList<String>();
+      
+   }
+   
+   public List<String> getClassNames()
+   {
+      return classNames;
+   }
+   
+   public List<String> getMethodNames()
+   {
+      return methodNames;
+   }
+   
+   public void run(boolean ignoreExpectedExceptions)
+   {
+      AbstractTest.setInContainer(true);
+      if (classNames.size() == 0)
+      {
+         DeploymentProperties deploymentProperties = new DeploymentProperties();
+         this.classNames = deploymentProperties.getPropertyValues("className");
+      }
+      TestNG testNG = new TestNG(false);
+      testNG.setVerbose(0);
+      BufferedListener listener = new BufferedListener();
+      testNG.addListener(listener);
+      List<XmlSuite> xmlSuites = new ArrayList<XmlSuite>();
+      testNG.setXmlSuites(xmlSuites);
+      xmlSuites.add(createSuite());
+      if (ignoreExpectedExceptions)
+      {
+         testNG.setAnnotationTransformer(new RemoveExpectedExceptionsAnnotationTransformer());
+      }
+      testNG.run();
+      this.context = listener.getContext();
+      this.testResults = listener.getTestResults();
+      this.configurationResults = listener.getConfigurationResults();
+   }
+    
+   
+   private XmlSuite createSuite()
+   {
+      XmlSuite suite = new XmlSuite();
+      suite.setName("JSR-299 TCK");
+      suite.setAnnotations("JDK5_ANNOTATION_TYPE");
+      for (String className : classNames)
+      {
+         XmlTest test = new XmlTest(suite);
+         test.setName("JSR-299 TCK" + className);
+         List<XmlClass> testClasses = new ArrayList<XmlClass>();
+         XmlClass testClass = new XmlClass(className);
+         for (String methodName : getMethodNames())
+         {
+            testClass.getIncludedMethods().add(methodName);
+         }
+         testClasses.add(testClass);
+         test.setXmlClasses(testClasses);
+      }
+      return suite;
+   }
+   
+   public ITestContext getContext()
+   {
+      return context;
+   }
+   
+   public List<ITestResult> getTestResults()
+   {
+      return testResults;
+   }
+   
+   public List<ITestResult> getConfigurationResults()
+   {
+      return configurationResults;
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/servlet/ServletTestLauncher.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/servlet/ServletTestLauncher.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/servlet/ServletTestLauncher.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,91 @@
+package org.jboss.testharness.impl.runner.servlet;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.lang.reflect.Method;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+
+import org.jboss.testharness.api.Configurable;
+import org.jboss.testharness.api.Configuration;
+import org.jboss.testharness.api.TestLauncher;
+import org.jboss.testharness.api.TestResult;
+import org.jboss.testharness.impl.runner.TestResultImpl;
+
+public class ServletTestLauncher implements TestLauncher, Configurable
+{
+
+   private Configuration configuration;
+   
+   public void setConfiguration(Configuration configuration)
+   {
+      this.configuration = configuration;
+   }
+   
+   public TestResultImpl launchTest(Method method) throws IOException
+   {
+      Class<?> testClass = method.getDeclaringClass();
+      String url = "http://" + configuration.getHost() + "/" + testClass.getName() + "/?outputMode=serializedObject&methodName=" + method.getName();
+      long timeoutTime = System.currentTimeMillis() + configuration.getConnectTimeout();
+      boolean interrupted = false;
+      while (timeoutTime > System.currentTimeMillis())
+      {
+         URLConnection connection = new URL(url).openConnection();
+         if (!(connection instanceof HttpURLConnection))
+         {
+            throw new IllegalStateException("Not an http connection! " + connection);
+         }
+         HttpURLConnection httpConnection = (HttpURLConnection) connection;
+         httpConnection.setUseCaches(false);
+         httpConnection.setDefaultUseCaches(false);
+         try
+         {
+            httpConnection.connect();
+            if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK)
+            {
+               ObjectInputStream ois = new ObjectInputStream(httpConnection.getInputStream());
+               Object o;
+               try
+               {
+                  o = ois.readObject();
+               }
+               catch (ClassNotFoundException e)
+               {
+                  throw new IOException(e);
+               }
+               ois.close();
+               if (!(o instanceof TestResult))
+               {
+                  throw new IllegalStateException("Error reading test results - expected a TestResult but got " + o);
+               }
+               TestResultImpl result = (TestResultImpl) o;
+               
+               return result;
+            }
+            else if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_NOT_FOUND)
+            {
+               throw new IllegalStateException("Error launching test " + testClass.getName() + " at " + url + ". Got " + httpConnection.getResponseCode() + " ("+ httpConnection.getResponseMessage() + ")");
+            }
+            try
+            {
+               Thread.sleep(200);
+            }
+            catch (InterruptedException e)
+            {
+               interrupted = true;
+            }
+         }
+         finally
+         {
+            httpConnection.disconnect();
+         }
+      }
+      if (interrupted)
+      {
+         Thread.currentThread().interrupt();
+      }
+      throw new IllegalStateException("Error launching test " + testClass.getName() + " at " + url + ". Kept on getting 404s.");
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/servlet/ServletTestRunner.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/servlet/ServletTestRunner.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/runner/servlet/ServletTestRunner.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,157 @@
+package org.jboss.testharness.impl.runner.servlet;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.testharness.api.TestResult;
+import org.jboss.testharness.impl.ConfigurationImpl;
+import org.jboss.testharness.impl.runner.TestResultImpl;
+import org.jboss.testharness.impl.runner.TestRunner;
+import org.testng.ITestResult;
+
+public class ServletTestRunner extends HttpServlet
+{
+   
+   
+  
+   @Override
+   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+   {
+      ConfigurationImpl.get().setStandalone(false);
+      TestRunner runner = new TestRunner();
+      String methodName = null;
+      if (req.getParameter("methodName") != null)
+      {
+         methodName = req.getParameter("methodName");
+         runner.getMethodNames().add(methodName);
+      }
+      String outputMode;
+      if (req.getParameter("outputMode") != null)
+      {
+         outputMode = (String) req.getParameter("outputMode");
+      }
+      else
+      {
+         outputMode = "html";
+      }
+      if (outputMode.equals("serializedObject") && methodName == null)
+      {
+         resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "No method name specified");
+         return;
+      }
+      
+      if (outputMode.equals("html"))
+      {
+         runner.run(false);
+         resp.setContentType("text/html");
+         resp.setStatus(HttpServletResponse.SC_OK);
+         PrintWriter writer = resp.getWriter();
+         writer.write("<html>\n");
+         writer.write("<head><title>TCK Report</title></head>\n");
+         writer.write("<body>\n");
+         writer.write("<h2>Configuration</h2>\n");
+         writer.write("<table>\n");
+         writer.write("<tr>\n");
+         writer.write("<td><b>Method</b></td><td><b>Status</b></td>\n");
+         writer.write("</tr>\n");
+         for (ITestResult result : runner.getContext().getFailedConfigurations().getAllResults())
+         {
+            writeResult(writer, result);
+         }
+         for (ITestResult result : runner.getContext().getSkippedConfigurations().getAllResults())
+         {
+            writeResult(writer, result);
+         }
+         writer.write("</table>\n");
+         writer.write("<h2>Tests</h2>\n");
+         writer.write("<table>\n");
+         writer.write("<tr>\n");
+         writer.write("<td><b>Method</b></td><td><b>Status</b></td>\n");
+         writer.write("</tr>\n");
+         for (ITestResult result : runner.getContext().getFailedTests().getAllResults())
+         {
+            writeResult(writer, result);
+         }
+         for (ITestResult result : runner.getContext().getPassedTests().getAllResults())
+         {
+            writeResult(writer, result);
+         }
+         for (ITestResult result : runner.getContext().getSkippedTests().getAllResults())
+         {
+            writeResult(writer, result);
+         }
+         writer.write("</table>\n");
+         writer.write("</body>\n");
+      }
+      else if (outputMode.equals("serializedObject"))
+      {
+         runner.run(true);
+         ObjectOutputStream oos = new ObjectOutputStream(resp.getOutputStream());
+         if (runner.getTestResults().size() == 1)
+         {
+            TestResult result;
+            if (runner.getTestResults().get(0).getStatus() == 3)
+            {
+               // This is a skip, so there was a configuration problem
+               // send that instead
+               result = TestResultImpl.of(runner.getConfigurationResults().get(0));
+            }
+            else
+            {
+               result = TestResultImpl.of(runner.getTestResults().get(0));
+            }
+            oos.writeObject(result);
+            resp.setStatus(HttpServletResponse.SC_OK);
+            oos.flush();
+            oos.close();
+         }
+         else
+         {
+            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ">1 result!");
+         }
+         
+      }
+      else
+      {
+         resp.sendError(500, "No report format specified");
+      }
+   }
+   
+   private static void writeResult(PrintWriter writer, ITestResult result)
+   {
+      writer.write("<tr>\n");
+      writer.write("<td>" + result.getMethod() + "</td>");
+      writer.write("<td>" + statusAsString(result.getStatus()) + "</td>");
+      writer.write("</tr>\n");
+      if (result.getStatus() == ITestResult.FAILURE)
+      {
+         writer.write("<tr>\n");
+         writer.write("<td colspan=\"2\"><pre>");
+         result.getThrowable().printStackTrace(writer);
+         writer.write("</pre></td>");
+         writer.write("</tr>\n");
+      }
+   }
+   
+   private static String statusAsString(int statusCode)
+   {
+      switch (statusCode)
+      {
+      case ITestResult.SUCCESS:
+         return "success";
+      case ITestResult.FAILURE:
+         return "failure";
+      case ITestResult.SKIP:
+         return "skipped";
+      default:
+         return "unknown";
+      }
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/testng/DisableIntegrationTestsMethodSelector.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/testng/DisableIntegrationTestsMethodSelector.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/testng/DisableIntegrationTestsMethodSelector.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,34 @@
+package org.jboss.testharness.impl.testng;
+
+import java.util.List;
+
+import org.jboss.testharness.impl.ConfigurationImpl;
+import org.jboss.testharness.impl.packaging.IntegrationTest;
+import org.testng.IMethodSelector;
+import org.testng.IMethodSelectorContext;
+import org.testng.ITestNGMethod;
+
+public class DisableIntegrationTestsMethodSelector implements IMethodSelector
+{
+
+   private static final long serialVersionUID = 6034298835828495024L;
+
+   public boolean includeMethod(IMethodSelectorContext context, ITestNGMethod method, boolean isTestMethod)
+   {
+      if (!ConfigurationImpl.get().isRunIntegrationTests() && method.getMethod().getDeclaringClass().isAnnotationPresent(IntegrationTest.class))
+      {
+         context.setStopped(true);
+         return false;
+      }
+      else
+      {
+         return true;
+      }
+   }
+
+   public void setTestMethods(List<ITestNGMethod> testMethods)
+   {
+      
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/testng/ExcludeIncontainerUnderInvestigationMethodSelector.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/testng/ExcludeIncontainerUnderInvestigationMethodSelector.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/testng/ExcludeIncontainerUnderInvestigationMethodSelector.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,36 @@
+package org.jboss.testharness.impl.testng;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.jboss.testharness.impl.ConfigurationImpl;
+import org.jboss.testharness.impl.packaging.IntegrationTest;
+import org.testng.IMethodSelector;
+import org.testng.IMethodSelectorContext;
+import org.testng.ITestNGMethod;
+
+public class ExcludeIncontainerUnderInvestigationMethodSelector implements IMethodSelector
+{
+   
+   private static final long serialVersionUID = 7261618804033064979L;
+
+   public boolean includeMethod(IMethodSelectorContext methodContext, ITestNGMethod method, boolean isTestMethod)
+   {
+      if (!ConfigurationImpl.get().isStandalone() || method.getMethod().getDeclaringClass().isAnnotationPresent(IntegrationTest.class))
+      {
+         List<String> groups = Arrays.asList(method.getGroups());
+         if (groups.contains("incontainer-ri-broken") || groups.contains("incontainer-broken"))
+         {
+            methodContext.setStopped(true);
+            return false;
+         }
+      }
+      return true;
+   }
+   
+   public void setTestMethods(List<ITestNGMethod> arg0)
+   {
+      
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/testng/RemoveExpectedExceptionsAnnotationTransformer.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/testng/RemoveExpectedExceptionsAnnotationTransformer.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/testng/RemoveExpectedExceptionsAnnotationTransformer.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,17 @@
+package org.jboss.testharness.impl.testng;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.testng.internal.annotations.IAnnotationTransformer;
+import org.testng.internal.annotations.ITest;
+
+public class RemoveExpectedExceptionsAnnotationTransformer implements IAnnotationTransformer
+{
+   
+   public void transform(ITest arg0, Class arg1, Constructor arg2, Method arg3)
+   {
+      arg0.setExpectedExceptions(new Class<?>[0]);
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/DeploymentProperties.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/DeploymentProperties.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/DeploymentProperties.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,232 @@
+package org.jboss.testharness.impl.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Utility class to load deployment properties
+ * 
+ * @author Pete Muir
+ */
+public class DeploymentProperties
+{
+   // The resource bundle used to control Web Beans RI deployment
+   public static final String RESOURCE_BUNDLE = "META-INF/web-beans-tck.properties";
+   
+   private static final Logger log = Logger.getLogger(DeploymentProperties.class);
+   
+   // The class to work from
+   private SimpleResourceLoader resourceLoader;
+
+   /**
+    * Constructor
+    * 
+    * @param classLoader The classloader to work on
+    */
+   public DeploymentProperties()
+   {
+      this.resourceLoader = new SimpleResourceLoader();
+   }
+
+   /**
+    * Get a list of possible values for a given key.
+    * 
+    * First, System properties are tried, followed by the specified resource
+    * bundle (first in classpath only).
+    * 
+    * @param key The key to search for
+    * @return A list of possible values. An empty list is returned if there are
+    *         no matches.
+    */
+   public List<String> getPropertyValues(String key)
+   {
+      List<String> values = new ArrayList<String>();
+      addPropertiesFromSystem(key, values);
+      addPropertiesFromResourceBundle(key, values);
+      return values;
+   }
+
+   /**
+    * Adds matches from system properties
+    * 
+    * @param key The key to match
+    * @param values The currently found values
+    */
+   private void addPropertiesFromSystem(String key, List<String> values)
+   {
+      addProperty(key, System.getProperty(key), values);
+   }
+
+   /**
+    * Adds matches from detected resource bundles
+    * 
+    * @param key The key to match
+    * @param values The currently found values
+    */
+   private void addPropertiesFromResourceBundle(String key, List<String> values)
+   {
+      try
+      {
+         for (URL url : resourceLoader.getResources(RESOURCE_BUNDLE))
+         {
+            Properties properties = new Properties();
+            InputStream propertyStream = url.openStream();
+            try
+            {
+               properties.load(propertyStream);
+               addProperty(key, properties.getProperty(key), values);
+            }
+            finally
+            {
+               if (propertyStream != null)
+               {
+                  propertyStream.close();
+               }
+            }
+         }
+      }
+      catch (IOException e)
+      {
+         // No - op, file is optional
+      }
+   }
+
+   /**
+    * Add the property to the set of properties only if it hasn't already been
+    * added
+    * 
+    * @param key The key searched for
+    * @param value The value of the property
+    * @param values The currently found values
+    */
+   private void addProperty(String key, String value, List<String> values)
+   {
+      if (value != null)
+      {
+         String[] properties = Strings.split(value, ":");
+         for (String property : properties)
+         {
+            values.add(property);
+         }
+
+      }
+   }
+   
+   /**
+    * Gets the possible implementation class for a given property for which the
+    * values are classanames
+    * 
+    * @param deploymentProperties The deployment properties object to use
+    * @param resourceLoader The resource laoder to use to attempt
+    * @param propertyName The name of the property to load
+    * @return A set of classes specified
+    */
+   @SuppressWarnings("unchecked")
+   public <T> Set<Class<T>> getClasses(String propertyName, Class<T> expectedType)
+   {
+      Set<Class<T>> classes = new HashSet<Class<T>>();
+      for (String className : getPropertyValues(propertyName))
+      {
+         try
+         {
+            classes.add((Class<T>) resourceLoader.classForName(className));
+         }
+         catch (ResourceLoadingException e)
+         {
+            //log.debug("Unable to load class " + className + " for property " + propertyName, e);
+         }
+      }
+      return classes;
+   }
+   
+   public <T> Class<T> getClassValue(String propertyName, Class<T> expectedType, boolean required)
+   {
+      Set<Class<T>> classes = getClasses(propertyName, expectedType);
+      if (classes.size() == 0)
+      {
+         if (required)
+         {
+            throw new IllegalArgumentException("Cannot find any implementations of " + expectedType.getSimpleName() + ", check that " + propertyName + " is specified");
+         }
+         else
+         {
+            return null;
+         }
+      }
+      else if (classes.size() > 1)
+      {
+         throw new IllegalArgumentException("More than one implementation of " + expectedType.getSimpleName() + " specified by " + propertyName + ", not sure which one to use!");
+      }
+      else
+      {
+         return classes.iterator().next(); 
+      }
+   }
+   
+   public <T> T getInstanceValue(String propertyName, Class<T> expectedType, boolean required)
+   {
+      Class<T> clazz = getClassValue(propertyName, expectedType, required);
+      if (clazz != null)
+      {
+         try
+         {
+            return clazz.newInstance();
+         }
+         catch (InstantiationException e)
+         {
+            throw new IllegalStateException("Error instantiating " + clazz + " specified by " + propertyName, e);
+         }
+         catch (IllegalAccessException e)
+         {
+            throw new IllegalStateException("Error instantiating " + clazz + " specified by " + propertyName, e);
+         }
+      }
+      else
+      {
+         return null;
+      }
+   }
+   
+   public boolean getBooleanValue(String propertyName, boolean _default, boolean required)
+   {
+      return Boolean.valueOf(getStringValue(propertyName, _default ? "true" : "false", required));
+   }
+   
+   public int getIntValue(String propertyName, int _default, boolean required)
+   {
+      return Integer.valueOf(getStringValue(propertyName, Integer.toString(_default), required)).intValue();
+   }
+   
+   public String getStringValue(String propertyName, String _default, boolean required)
+   {
+      List<String> values = getPropertyValues(propertyName);
+      if (values.size() == 0)
+      {
+         if (required)
+         {
+            throw new IllegalArgumentException("Cannot find required property " + propertyName + ", check that it is specified");
+         }
+         else
+         {
+            return _default;
+         }
+      }
+      else if (values.size() > 1)
+      {
+         throw new IllegalArgumentException("More than one value given for " + propertyName + ", not sure which one to use!");
+      }
+      else
+      {
+         return values.iterator().next();
+      }
+   }
+
+}
\ No newline at end of file

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/EnumerationIterable.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/EnumerationIterable.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/EnumerationIterable.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,37 @@
+package org.jboss.testharness.impl.util;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+
+/**
+ * An Enumeration -> Iteratble adaptor
+ *  
+ * @author Pete Muir
+ * @see org.jboss.webbeans.util.EnumerationIterator
+ */
+class EnumerationIterable<T> implements Iterable<T>
+{
+   // The enumeration-iteartor
+   private EnumerationIterator<T> iterator;
+   
+   /**
+    * Constructor
+    * 
+    * @param enumeration The enumeration
+    */
+   public EnumerationIterable(Enumeration<T> enumeration)
+   {
+      this.iterator = new EnumerationIterator<T>(enumeration);
+   }
+   
+   /**
+    * Gets an iterator
+    * 
+    * @return The iterator
+    */
+   public Iterator<T> iterator()
+   {
+      return iterator;
+   }
+   
+}
\ No newline at end of file

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/EnumerationIterator.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/EnumerationIterator.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/EnumerationIterator.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,55 @@
+package org.jboss.testharness.impl.util;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+
+/**
+ * An enumeration -> iterator adapter
+ *  
+ * @author Pete Muir
+ */
+ at SuppressWarnings("unchecked")
+class EnumerationIterator<T> implements Iterator<T>
+{
+   // The enumeration
+   private Enumeration e;
+
+   /**
+    * Constructor
+    * 
+    * @param e The enumeration
+    */
+   public EnumerationIterator(Enumeration e)
+   {
+      this.e = e;
+   }
+
+   /**
+    * Indicates if there are more items to iterate
+    * 
+    * @return True if more, false otherwise
+    */
+   public boolean hasNext()
+   {
+      return e.hasMoreElements();
+   }
+
+   /**
+    * Gets the next item
+    * 
+    * @return The next items
+    */
+   public T next()
+   {
+      return (T) e.nextElement();
+   }
+
+   /**
+    * Removes an item. Not supported
+    */
+   public void remove()
+   {
+      throw new UnsupportedOperationException();
+   }
+   
+}
\ No newline at end of file

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/Files.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/Files.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/Files.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,36 @@
+package org.jboss.testharness.impl.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class Files
+{
+   
+   public static void copy(InputStream source, OutputStream destination) throws IOException
+   {
+      byte[] readBuffer = new byte[2156]; 
+      int bytesIn = 0; 
+      while((bytesIn = source.read(readBuffer)) != -1) 
+      { 
+         destination.write(readBuffer, 0, bytesIn); 
+      }
+   }
+
+   public static void copy(InputStream inputStream, File file) throws IOException
+   {
+      OutputStream os = new FileOutputStream(file);
+      try 
+      {
+         copy(inputStream, os);
+     } 
+     finally 
+     {
+         os.close();
+     }
+   
+   }
+   
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/Reflections.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/Reflections.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/Reflections.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,118 @@
+package org.jboss.testharness.impl.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.testharness.impl.packaging.ArtifactDescriptor;
+
+/**
+ * Utility class for static reflection-type operations
+ * 
+ * @author Pete Muir
+ * 
+ */
+public class Reflections
+{
+   /**
+    * Checks if all annotations are in a given set of annotations
+    * 
+    * @param annotations The annotation set
+    * @param annotationTypes The annotations to match
+    * @return True if match, false otherwise
+    */
+   public static boolean annotationSetMatches(Set<Annotation> annotations, Class<? extends Annotation>... annotationTypes)
+   {
+      List<Class<? extends Annotation>> annotationTypeList = new ArrayList<Class<? extends Annotation>>();
+      annotationTypeList.addAll(Arrays.asList(annotationTypes));
+      for (Annotation annotation : annotations)
+      {
+         if (annotationTypeList.contains(annotation.annotationType()))
+         {
+            annotationTypeList.remove(annotation.annotationType());
+         }
+         else
+         {
+            return false;
+         }
+      }
+      return annotationTypeList.size() == 0;
+   }
+   
+   public static InputStream loadResourceAsStream(String name)
+   {
+      InputStream is = null;
+      if (Thread.currentThread().getContextClassLoader() != null)
+      {
+         is = Thread.currentThread().getContextClassLoader().getResourceAsStream(name);
+      }
+      if (is == null)
+      {
+         is = ArtifactDescriptor.class.getResourceAsStream(name);
+      }
+      return is;
+   }
+   
+   public static URL loadResource(String name)
+   {
+      URL url = null;
+      if (Thread.currentThread().getContextClassLoader() != null)
+      {
+         url = Thread.currentThread().getContextClassLoader().getResource(name);
+      }
+      if (url == null)
+      {
+         url = ArtifactDescriptor.class.getResource(name);
+      }
+      return url;
+   }
+   
+   public static Class<?> loadClass(String name)
+   {
+      Class<?> clazz = null;
+      if (Thread.currentThread().getContextClassLoader() != null)
+      {
+         try
+         {
+            clazz = Thread.currentThread().getContextClassLoader().loadClass(name);
+         }
+         catch (ClassNotFoundException e)
+         {
+            // no-op
+         }
+      }
+      if (clazz == null)
+      {
+         try
+         {
+            clazz = Class.forName(name);
+         }
+         catch (ClassNotFoundException e)
+         {
+            // No-op
+         }
+      }
+      return clazz;
+   }
+   
+   public static Iterable<URL> loadResources(String name) throws IOException
+   {
+      Enumeration<URL> urls = null;
+      if (Thread.currentThread().getContextClassLoader() != null)
+      {
+         urls = Thread.currentThread().getContextClassLoader().getResources(name);
+      }
+      if (urls == null)
+      {
+         urls = ArtifactDescriptor.class.getClassLoader().getResources(name);
+      }
+      return new EnumerationIterable<URL>(urls);
+   }
+
+}

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/ResourceLoadingException.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/ResourceLoadingException.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/ResourceLoadingException.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,53 @@
+package org.jboss.testharness.impl.util;
+
+
+/**
+ * Exception thrown when errors occur while loading resource
+ * 
+ * @author Pete Muir
+ *
+ */
+class ResourceLoadingException extends RuntimeException
+{
+   private static final long serialVersionUID = 1L;
+
+   /**
+    * Constructor
+    */
+   public ResourceLoadingException()
+   {
+      super();
+   }
+
+   /**
+    * Constructor
+    * 
+    * @param message The message
+    * @param throwable The exception
+    */
+   public ResourceLoadingException(String message, Throwable throwable)
+   {
+      super(message, throwable);
+   }
+
+   /**
+    * Constructor
+    * 
+    * @param message The message
+    */
+   public ResourceLoadingException(String message)
+   {
+      super(message);
+   }
+
+   /**
+    * Constructor
+    * 
+    * @param throwable The exception
+    */
+   public ResourceLoadingException(Throwable throwable)
+   {
+      super(throwable);
+   }
+   
+}
\ No newline at end of file

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/SimpleResourceLoader.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/SimpleResourceLoader.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/SimpleResourceLoader.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,43 @@
+package org.jboss.testharness.impl.util;
+
+import java.io.IOException;
+import java.net.URL;
+
+class SimpleResourceLoader
+{
+   
+   public Class<?> classForName(String name)
+   {
+      
+      try
+      {
+         return Class.forName(name);
+      }
+      catch (ClassNotFoundException e)
+      {
+         throw new ResourceLoadingException(e);
+      }
+      catch (NoClassDefFoundError e)
+      {
+         throw new ResourceLoadingException(e);
+      }
+   }
+   
+   public URL getResource(String name)
+   {
+      return getClass().getResource(name);
+   }
+   
+   public Iterable<URL> getResources(String name)
+   {
+      try
+      {
+         return new EnumerationIterable<URL>(getClass().getClassLoader().getResources(name));
+      }
+      catch (IOException e)
+      {
+         throw new ResourceLoadingException(e);
+      }
+   }
+   
+}
\ No newline at end of file

Added: test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/Strings.java
===================================================================
--- test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/Strings.java	                        (rev 0)
+++ test-harness/trunk/impl/src/main/java/org/jboss/testharness/impl/util/Strings.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,30 @@
+package org.jboss.testharness.impl.util;
+
+import java.util.StringTokenizer;
+
+public class Strings
+{
+   static String[] split(String strings, String delims)
+   {
+      if (strings == null)
+      {
+         return new String[0];
+      }
+      else
+      {
+         StringTokenizer tokens = new StringTokenizer(strings, delims);
+         String[] result = new String[tokens.countTokens()];
+         int i = 0;
+         while (tokens.hasMoreTokens())
+         {
+            result[i++] = tokens.nextToken();
+         }
+         return result;
+      }
+   }
+   
+   public static boolean isEmpty(String string)
+   {
+      return string == null || string.length() == 0;
+   }
+}

Added: test-harness/trunk/impl/src/main/resources/org/jboss/testharness/impl/packaging/war/web.xml
===================================================================
--- test-harness/trunk/impl/src/main/resources/org/jboss/testharness/impl/packaging/war/web.xml	                        (rev 0)
+++ test-harness/trunk/impl/src/main/resources/org/jboss/testharness/impl/packaging/war/web.xml	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<web-app version="2.5"
+    xmlns="http://java.sun.com/xml/ns/javaee"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
+   
+   <display-name>JBoss Test Harness</display-name>
+   
+   <servlet>
+      <servlet-name>JBoss Test Harness Test Runner</servlet-name>
+      <servlet-class>org.jboss.testharness.impl.runner.servlet.ServletTestRunner</servlet-class>
+   </servlet>
+   
+   <servlet-mapping>
+      <servlet-name>JBoss Test Harness Test Runner</servlet-name>
+      <url-pattern>/*</url-pattern>
+   </servlet-mapping>
+
+</web-app>

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/impl/packaging/ear/ejb-jar.xml
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/impl/packaging/ear/ejb-jar.xml	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/impl/packaging/ear/ejb-jar.xml	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" 
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
+         version="3.0">
+   
+</ejb-jar>

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/mock/MockConfiguration.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/mock/MockConfiguration.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/mock/MockConfiguration.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,8 @@
+package org.jboss.testharness.test.impl.mock;
+
+import org.jboss.testharness.impl.ConfigurationImpl;
+
+public class MockConfiguration extends ConfigurationImpl
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/AbstractArtifactTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/AbstractArtifactTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/AbstractArtifactTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,134 @@
+package org.jboss.testharness.test.impl.packaging;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.util.Arrays;
+
+public abstract class AbstractArtifactTest
+{
+   
+   protected static final FilenameFilter WEB_INF_FILTER = new FilenameFilter()
+   {
+      public boolean accept(File dir, String name)
+      {
+         return name.equals("WEB-INF");
+      }
+   };
+   
+   protected static final FilenameFilter CLASSES_FILTER = new FilenameFilter()
+   {
+      public boolean accept(File dir, String name)
+      {
+         return name.equals("classes");
+      }
+   };
+   
+   protected static final FilenameFilter META_INF_FILTER = new FilenameFilter()
+   {
+      public boolean accept(File dir, String name)
+      {
+         return name.equals("META-INF");
+      }
+   };
+   
+   protected static final FilenameFilter BEANS_XML_FILTER = new FilenameFilter()
+   {
+      
+     public boolean accept(File dir, String name)
+      {
+         return name.equals("beans.xml");
+      } 
+      
+   };
+   
+   
+   
+   protected static final FilenameFilter WEB_XML_FILTER = new FilenameFilter()
+   {
+      
+     public boolean accept(File dir, String name)
+      {
+         return name.equals("web.xml");
+      } 
+      
+   };
+   
+   protected File getCurrentPackageAsFile(File root)
+   {
+      return getPackageAsFile(getClass().getPackage(), root);
+   }
+   
+   protected File getPackageAsFile(Package pkg, File root)
+   {
+      String[] packageHierarchy = pkg.getName().split("\\.");
+      for (final String packageName : packageHierarchy)
+      {
+         File[] files = root.listFiles(new FilenameFilter()
+         {
+            
+            public boolean accept(File dir, String name)
+            {
+               return name.equals(packageName);
+            }
+            
+         });
+         if (files.length == 1)
+         {
+            root = files[0];
+         }
+         else
+         {
+            throw new IllegalStateException("Unable to traverse package hierarchy " + Arrays.asList(packageHierarchy) + ", unable to open directory " + packageName);
+         }
+      }
+      return root;
+   }
+   
+   protected String readFile(File file) throws IOException
+   {
+      if (file.isFile())
+      {
+         Reader reader = new InputStreamReader(new BufferedInputStream(new FileInputStream(file)));
+         StringBuffer buffer = new StringBuffer(1024);
+         char[] bytes = new char[1024];
+         while (reader.read(bytes) > -1)
+         {
+            buffer.append(String.valueOf(bytes));
+         }
+         reader.close();
+         return buffer.toString();
+      }
+      else
+      {
+         return null;
+      }
+   }
+   
+   protected static void copy(InputStream inputStream, File file) throws IOException
+   {
+      OutputStream os = new FileOutputStream(file);
+      try 
+      {
+         byte[] buf = new byte[1024];
+         int i = 0;
+         while ((i = inputStream.read(buf)) != -1) 
+         {
+             os.write(buf, 0, i);
+         }
+     } 
+     finally 
+     {
+         os.close();
+     }
+
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/Cow.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/Cow.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/Cow.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.declarative.ear;
+
+class Cow
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/DeclarativeEarTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/DeclarativeEarTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/DeclarativeEarTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,39 @@
+package org.jboss.testharness.test.impl.packaging.declarative.ear;
+
+import java.io.File;
+
+import org.jboss.testharness.api.Configuration;
+import org.jboss.testharness.impl.packaging.ArtifactGenerator;
+import org.jboss.testharness.impl.packaging.ear.EarArtifactDescriptor;
+import org.jboss.testharness.impl.packaging.jsr299.TCKArtifactDescriptor;
+import org.jboss.testharness.test.impl.mock.MockConfiguration;
+import org.jboss.testharness.test.impl.packaging.AbstractArtifactTest;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class DeclarativeEarTest extends AbstractArtifactTest
+{
+   
+   private Configuration configuration;
+   
+   @BeforeClass
+   public void beforeClass()
+   {
+      configuration = new MockConfiguration();
+      configuration.setStandalone(false);
+   }
+   
+   @Test
+   public void testDeclarativeEar() throws Exception
+   {
+      TCKArtifactDescriptor artifact = new ArtifactGenerator(configuration).createArtifact(DummyTest.class);
+      assert artifact instanceof EarArtifactDescriptor;
+      EarArtifactDescriptor earArtifact = (EarArtifactDescriptor) artifact;
+      assert artifact.getExplodedJar().list().length == 4;
+      File currentPackage = getCurrentPackageAsFile(earArtifact.getEjbJar().getExplodedJar());
+      assert new File(currentPackage, "Cow.class").isFile();
+      assert new File(currentPackage, "DummyTest.class").isFile();
+      assert new File(currentPackage, "Fox.class").isFile();
+   }
+     
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/DummyTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/DummyTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/DummyTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,20 @@
+package org.jboss.testharness.test.impl.packaging.declarative.ear;
+
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.IntegrationTest;
+import org.jboss.testharness.impl.packaging.Packaging;
+import org.jboss.testharness.impl.packaging.PackagingType;
+
+
+ at Artifact
+ at IntegrationTest
+ at Packaging(PackagingType.EAR)
+class DummyTest
+{
+   
+   public void test()
+   {
+      assert true;
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/Fox.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/Fox.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/ear/Fox.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.declarative.ear;
+
+class Fox
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/Cow.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/Cow.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/Cow.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.declarative.standalone;
+
+class Cow
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DeclarativeStandaloneTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DeclarativeStandaloneTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DeclarativeStandaloneTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,162 @@
+package org.jboss.testharness.test.impl.packaging.declarative.standalone;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+import org.jboss.testharness.api.Configuration;
+import org.jboss.testharness.impl.packaging.ArtifactGenerator;
+import org.jboss.testharness.impl.packaging.ear.EarArtifactDescriptor;
+import org.jboss.testharness.impl.packaging.jsr299.TCKArtifactDescriptor;
+import org.jboss.testharness.impl.packaging.war.WarArtifactDescriptor;
+import org.jboss.testharness.test.impl.mock.MockConfiguration;
+import org.jboss.testharness.test.impl.packaging.AbstractArtifactTest;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class DeclarativeStandaloneTest extends AbstractArtifactTest
+{
+   
+   private Configuration standaloneConfiguration;
+   private Configuration nonStandaloneConfiguration;
+   
+   @BeforeClass
+   public void beforeClass()
+   {
+      standaloneConfiguration = new MockConfiguration();
+      standaloneConfiguration.setStandalone(true);
+      nonStandaloneConfiguration = new MockConfiguration();
+      nonStandaloneConfiguration.setStandalone(false);
+   }
+   
+   @Test
+   public void testDefaultDeclartiveArtifact() throws Exception
+   {
+      TCKArtifactDescriptor artifact = new ArtifactGenerator(standaloneConfiguration).createArtifact(DummyTest.class);
+      assert artifact.getClass().equals(TCKArtifactDescriptor.class);
+      assert artifact.isUnit();
+      File root = artifact.getExplodedJar();
+      File currentPackage = getCurrentPackageAsFile(root);
+      File[] cowClasses = currentPackage.listFiles(new FilenameFilter()
+      {
+         
+         public boolean accept(File dir, String name)
+         {
+            return name.equals("Cow.class");
+         }
+         
+      });
+      assert cowClasses.length == 1;
+      assert cowClasses[0].getName().equals("Cow.class");
+      assert cowClasses[0].isFile();
+      File[] foxClasses = currentPackage.listFiles(new FilenameFilter()
+      {
+         
+         public boolean accept(File dir, String name)
+         {
+            return name.equals("Fox.class");
+         }
+         
+      });
+      assert foxClasses.length == 1;
+      assert foxClasses[0].getName().equals("Fox.class");
+      assert foxClasses[0].isFile();
+      
+      File[] testClasses = currentPackage.listFiles(new FilenameFilter()
+      {
+         
+         public boolean accept(File dir, String name)
+         {
+            return name.startsWith("DummyTest");
+         }
+         
+      });
+      assert testClasses.length == 1;
+      
+      assert root.listFiles(META_INF_FILTER).length == 1;
+      File metaInf = root.listFiles(META_INF_FILTER)[0];
+      assert metaInf.listFiles().length == 1;
+      assert metaInf.listFiles(BEANS_XML_FILTER).length == 1;
+      assert metaInf.listFiles(BEANS_XML_FILTER)[0].length() == 0;
+   }
+   
+   @Test
+   public void testClassesSpecifiedArtifact() throws Exception
+   {
+      TCKArtifactDescriptor artifact = new ArtifactGenerator(standaloneConfiguration).createArtifact(DummyClassesSpecifiedTest.class);
+      File root = artifact.getExplodedJar();
+      File currentPackage = getCurrentPackageAsFile(root);
+      assert currentPackage.listFiles().length == 1;
+      File[] subPackages = currentPackage.listFiles(new FilenameFilter()
+      {
+         
+         public boolean accept(File dir, String name)
+         {
+            return name.startsWith("subpackage");
+         }
+         
+      });
+      assert subPackages.length == 1;
+      File subPackage = subPackages[0];
+      assert subPackage.listFiles().length == 1;
+      assert subPackage.listFiles()[0].getName().equals("Rat.class");
+   }
+   
+   @Test
+   public void testResourcesSpecifiedArtifact() throws Exception
+   {
+      TCKArtifactDescriptor artifact = new ArtifactGenerator(standaloneConfiguration).createArtifact(DummyResourcesSpecifiedTest.class);
+      File root = artifact.getExplodedJar();
+      assert root.listFiles(META_INF_FILTER).length == 1;
+      File metaInf = root.listFiles(META_INF_FILTER)[0];
+      assert metaInf.listFiles(new FilenameFilter()
+      {
+         
+         public boolean accept(File dir, String name)
+         {
+            return name.equals("bar.xml");
+         }
+         
+      }).length == 1;
+   }
+   
+   @Test
+   public void testIntegrationTestDeclartiveArtifact() throws Exception
+   {
+      TCKArtifactDescriptor artifact = new ArtifactGenerator(standaloneConfiguration).createArtifact(DummyIntegrationTest.class);
+      assert !artifact.isUnit();
+   }
+   
+   @Test
+   public void testCustomBeansXml() throws Exception
+   {
+      TCKArtifactDescriptor artifact = new ArtifactGenerator(standaloneConfiguration).createArtifact(DummyCustomBeansXmlTest.class);
+      File root = artifact.getExplodedJar();
+      File metaInf = root.listFiles(META_INF_FILTER)[0];
+      assert metaInf.listFiles(BEANS_XML_FILTER).length == 1;
+      assert metaInf.listFiles(BEANS_XML_FILTER)[0].length() != 0;
+      String beans = readFile(metaInf.listFiles(BEANS_XML_FILTER)[0]);
+      assert beans.startsWith("<my></my>");
+   }
+   
+   @Test
+   public void testEjbTestDeclartiveArtifact() throws Exception
+   {
+      TCKArtifactDescriptor artifact = new ArtifactGenerator(nonStandaloneConfiguration).createArtifact(DummyEjbTest.class);
+      assert artifact.getClass().equals(EarArtifactDescriptor.class);
+   }
+   
+   @Test
+   public void testStandaloneEjbTestDeclartiveArtifact() throws Exception
+   {
+      TCKArtifactDescriptor artifact = new ArtifactGenerator(standaloneConfiguration).createArtifact(DummyEjbTest.class);
+      assert artifact.getClass().equals(TCKArtifactDescriptor.class);
+   }
+   
+   @Test
+   public void testWarDeclarativePackaging()
+   {
+      TCKArtifactDescriptor artifact = new ArtifactGenerator(nonStandaloneConfiguration).createArtifact(DummyWarUnitTest.class);
+      assert artifact.getClass().equals(WarArtifactDescriptor.class);
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyClassesSpecifiedTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyClassesSpecifiedTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyClassesSpecifiedTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,18 @@
+package org.jboss.testharness.test.impl.packaging.declarative.standalone;
+
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.Classes;
+import org.jboss.testharness.test.impl.packaging.declarative.standalone.subpackage.Rat;
+
+
+ at Artifact(addCurrentPackage=false)
+ at Classes(Rat.class)
+class DummyClassesSpecifiedTest
+{
+   
+   public void test()
+   {
+      assert true;
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyCustomBeansXmlTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyCustomBeansXmlTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyCustomBeansXmlTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,16 @@
+package org.jboss.testharness.test.impl.packaging.declarative.standalone;
+
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.jsr299.BeansXml;
+
+
+ at Artifact @BeansXml(value="my-web-beans.xml")
+class DummyCustomBeansXmlTest
+{
+   
+   public void test()
+   {
+      assert true;
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyEjbTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyEjbTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyEjbTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,17 @@
+package org.jboss.testharness.test.impl.packaging.declarative.standalone;
+
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.Packaging;
+import org.jboss.testharness.impl.packaging.PackagingType;
+
+
+ at Artifact @Packaging(PackagingType.EAR)
+class DummyEjbTest
+{
+   
+   public void test()
+   {
+      assert true;
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyIntegrationTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyIntegrationTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyIntegrationTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,17 @@
+package org.jboss.testharness.test.impl.packaging.declarative.standalone;
+
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.IntegrationTest;
+
+
+ at Artifact
+ at IntegrationTest
+class DummyIntegrationTest
+{
+   
+   public void test()
+   {
+      assert true;
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyResourcesSpecifiedTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyResourcesSpecifiedTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyResourcesSpecifiedTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,18 @@
+package org.jboss.testharness.test.impl.packaging.declarative.standalone;
+
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.Resource;
+import org.jboss.testharness.impl.packaging.Resources;
+
+
+ at Artifact(addCurrentPackage=false)
+ at Resources(value=@Resource(destination = "/META-INF/bar.xml", source="foo/foo.xml"))
+class DummyResourcesSpecifiedTest
+{
+   
+   public void test()
+   {
+      assert true;
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,15 @@
+package org.jboss.testharness.test.impl.packaging.declarative.standalone;
+
+import org.jboss.testharness.impl.packaging.Artifact;
+
+
+ at Artifact
+class DummyTest
+{
+   
+   public void test()
+   {
+      assert true;
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyWarUnitTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyWarUnitTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/DummyWarUnitTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,18 @@
+package org.jboss.testharness.test.impl.packaging.declarative.standalone;
+
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.Packaging;
+import org.jboss.testharness.impl.packaging.PackagingType;
+
+
+ at Artifact
+ at Packaging(PackagingType.WAR)
+class DummyWarUnitTest
+{
+   
+   public void test()
+   {
+      assert true;
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/Fox.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/Fox.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/Fox.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.declarative.standalone;
+
+class Fox
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/subpackage/Rat.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/subpackage/Rat.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/standalone/subpackage/Rat.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.declarative.standalone.subpackage;
+
+public class Rat
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/Cow.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/Cow.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/Cow.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.declarative.war;
+
+class Cow
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/DeclarativeWarTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/DeclarativeWarTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/DeclarativeWarTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,41 @@
+package org.jboss.testharness.test.impl.packaging.declarative.war;
+
+import java.io.File;
+
+import org.jboss.testharness.api.Configuration;
+import org.jboss.testharness.impl.packaging.ArtifactGenerator;
+import org.jboss.testharness.impl.packaging.jsr299.TCKArtifactDescriptor;
+import org.jboss.testharness.test.impl.mock.MockConfiguration;
+import org.jboss.testharness.test.impl.packaging.AbstractArtifactTest;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class DeclarativeWarTest extends AbstractArtifactTest
+{
+   
+   private Configuration configuration;
+   
+   @BeforeClass
+   public void beforeClass()
+   {
+      configuration = new MockConfiguration();
+      configuration.setStandalone(false);
+   }
+   
+   @Test
+   public void testDefaultWebXml() throws Exception
+   {
+      TCKArtifactDescriptor artifact = new ArtifactGenerator(configuration).createArtifact(DummyTest.class);
+      File root = artifact.getExplodedJar();
+      assert root.listFiles(WEB_INF_FILTER).length == 1;
+      File webInf = root.listFiles(WEB_INF_FILTER)[0];
+      assert webInf.getName().equals("WEB-INF");
+      assert webInf.isDirectory();
+      assert webInf.listFiles(WEB_XML_FILTER).length == 1;
+      File webXml = webInf.listFiles(WEB_XML_FILTER)[0];
+      assert webXml.isFile();
+      assert webXml.getName().equals("web.xml");
+      assert webXml.length() != 0;
+   }
+     
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/DummyTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/DummyTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/DummyTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,20 @@
+package org.jboss.testharness.test.impl.packaging.declarative.war;
+
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.IntegrationTest;
+import org.jboss.testharness.impl.packaging.Packaging;
+import org.jboss.testharness.impl.packaging.PackagingType;
+
+
+ at Artifact
+ at IntegrationTest
+ at Packaging(PackagingType.WAR)
+class DummyTest
+{
+   
+   public void test()
+   {
+      assert true;
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/Fox.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/Fox.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/declarative/war/Fox.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.declarative.war;
+
+class Fox
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/ear/Cow.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/ear/Cow.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/ear/Cow.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.ear;
+
+class Cow
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/ear/DummyTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/ear/DummyTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/ear/DummyTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.ear;
+
+public class DummyTest
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/ear/EarArtifactTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/ear/EarArtifactTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/ear/EarArtifactTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,154 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.ear;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import org.jboss.testharness.AbstractTest;
+import org.jboss.testharness.impl.packaging.ear.EarArtifactDescriptor;
+import org.jboss.testharness.test.impl.packaging.AbstractArtifactTest;
+import org.testng.annotations.Test;
+
+public class EarArtifactTest extends AbstractArtifactTest
+{
+   @Test
+   public void testDefaultEar() throws Exception
+   {
+      EarArtifactDescriptor ear = new EarArtifactDescriptor(DummyTest.class, null);
+      ear.getClasses().add(Cow.class);
+      File root = ear.getExplodedJar();
+      assert root.isDirectory();
+      assert root.listFiles().length == 4;
+      
+      File warRoot = ear.getWar().getExplodedJar();
+      assert warRoot.listFiles().length == 1;
+      assert warRoot.isDirectory();
+      assert warRoot.listFiles(WEB_INF_FILTER).length == 1;
+      File webInf = warRoot.listFiles(WEB_INF_FILTER)[0];
+      assert webInf.getName().equals("WEB-INF");
+      assert webInf.isDirectory();
+      assert webInf.listFiles().length == 1;
+      assert webInf.listFiles(WEB_XML_FILTER).length == 1;
+      File webXml = webInf.listFiles(WEB_XML_FILTER)[0];
+      assert webXml.isFile();
+      assert webXml.getName().equals("web.xml");
+      assert webXml.length() != 0;
+      assert !new File(webInf, "beans.xml").exists();
+      
+      File webInfLib = new File(webInf, "lib");
+      assert !webInfLib.exists();
+      
+      File webInfClasses = new File(webInf, "classes");
+      assert !webInfClasses.exists();
+      
+      File ejbJar = new File(root, DummyTest.class.getName() + ".jar");
+      assert ejbJar.exists();
+      assert ejbJar.length() > 0;
+      
+      File war = new File(root, DummyTest.class.getName() + ".war");
+      assert war.exists();
+      assert war.length() > 0;
+      
+      File lib = new File(root, "lib");
+      assert lib.isDirectory();
+      assert lib.list().length == 3;
+      List<String> libs = Arrays.asList(lib.list());
+      assert libs.contains("jboss-test-harness-api.jar");
+      assert libs.contains("testng.jar");
+      assert libs.contains("tck-support.jar");
+      
+      File metaInf = new File(root, "META-INF");
+      assert metaInf.isDirectory();
+      assert metaInf.list().length == 2;
+      List<String> metaInfs = Arrays.asList(metaInf.list());
+      assert metaInfs.contains("application.xml");
+      
+      File applicationXml = new File(metaInf, "application.xml");
+      assert applicationXml.length() > 0;
+      
+      File webBeansTckProperties = new File(metaInf, "web-beans-tck.properties");
+      assert webBeansTckProperties.isFile();
+      assert webBeansTckProperties.length() > 0;
+      
+      File ejbJarRoot = ear.getEjbJar().getExplodedJar();
+      
+      File ejbJarXml = new File(ejbJarRoot, "META-INF/ejb-jar.xml");
+      assert ejbJarXml.isFile();
+      assert ejbJarXml.length() > 0;
+      
+      File webbeansXml = new File(ejbJarRoot, "META-INF/beans.xml");
+      assert webbeansXml.isFile();
+      assert webbeansXml.length() == 0;
+      
+
+      
+      File currentPackage = getCurrentPackageAsFile(ejbJarRoot);
+      File[] cowClasses = currentPackage.listFiles(new FilenameFilter()
+      {
+         
+         public boolean accept(File dir, String name)
+         {
+            return name.equals("Cow.class");
+         }
+         
+      });
+      assert cowClasses.length == 1;
+      assert cowClasses[0].getName().equals("Cow.class");
+      assert cowClasses[0].isFile();
+      File tckPackage = getPackageAsFile(AbstractTest.class.getPackage(), ejbJarRoot);
+      File[] abstractTestClasses = tckPackage.listFiles(new FilenameFilter()
+      {
+         
+         public boolean accept(File dir, String name)
+         {
+            return name.equals("AbstractTest.class");
+         }
+         
+      });
+      
+      
+   }
+   
+   @Test
+   public void testJarProduction() throws Exception
+   {
+      EarArtifactDescriptor ear = new EarArtifactDescriptor(DummyTest.class, null);
+      ear.getClasses().add(Cow.class);
+      JarInputStream is = new JarInputStream(ear.getJarAsStream());
+      JarEntry entry;
+      List<String> fileNames = new ArrayList<String>();
+      while ((entry = is.getNextJarEntry()) != null)
+      {
+         fileNames.add(entry.getName().replace(File.separator, "/"));
+      }
+      is.close();
+      assert fileNames.contains("META-INF/application.xml");
+      assert fileNames.contains("META-INF/web-beans-tck.properties");
+      assert fileNames.contains("lib/tck-support.jar");
+      assert fileNames.contains(DummyTest.class.getName() + ".jar");
+      assert fileNames.contains(DummyTest.class.getName() + ".war");
+      
+      
+      File ejbJar = new File(ear.getExplodedJar(), DummyTest.class.getName() + ".jar");
+      assert ejbJar.exists();
+      assert ejbJar.isFile();
+      assert ejbJar.length() > 0;
+      is = new JarInputStream(new FileInputStream(ejbJar));
+      fileNames = new ArrayList<String>();
+      while ((entry = is.getNextJarEntry()) != null)
+      {
+         fileNames.add(entry.getName().replace(File.separator, "/"));
+      }
+      is.close();
+      assert fileNames.contains("META-INF/ejb-jar.xml");
+      assert fileNames.contains("META-INF/beans.xml");
+      assert fileNames.contains("org/jboss/testharness/test/impl/packaging/descriptors/ear/Cow.class");
+   }
+
+}
+

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/packages/ArtifactTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/packages/ArtifactTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/packages/ArtifactTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,59 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.packages;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+import org.jboss.testharness.impl.packaging.ArtifactDescriptor;
+import org.jboss.testharness.test.impl.packaging.AbstractArtifactTest;
+import org.testng.annotations.Test;
+
+public class ArtifactTest extends AbstractArtifactTest
+{
+   
+   @Test
+   public void testAllClassesInPackage() throws Exception
+   {
+      ArtifactDescriptor artifactDescriptor = new ArtifactDescriptor(null);
+      artifactDescriptor.addPackage(ArtifactTest.class.getPackage());
+      File root = artifactDescriptor.getExplodedJar();
+      File currentPackage = getCurrentPackageAsFile(root);
+      assert currentPackage.listFiles().length == 6;
+      File[] cowClasses = currentPackage.listFiles(new FilenameFilter()
+      {
+         
+         public boolean accept(File dir, String name)
+         {
+            return name.equals("Cow.class");
+         }
+         
+      });
+      assert cowClasses.length == 1;
+      assert cowClasses[0].getName().equals("Cow.class");
+      assert cowClasses[0].isFile();
+      File[] foxClasses = currentPackage.listFiles(new FilenameFilter()
+      {
+         
+         public boolean accept(File dir, String name)
+         {
+            return name.equals("Fox.class");
+         }
+         
+      });
+      assert foxClasses.length == 1;
+      assert foxClasses[0].getName().equals("Fox.class");
+      assert foxClasses[0].isFile();
+      
+      File[] testClasses = currentPackage.listFiles(new FilenameFilter()
+      {
+         
+         public boolean accept(File dir, String name)
+         {
+            return name.startsWith("ArtifactTest");
+         }
+         
+      });
+      assert testClasses.length == 4;
+      
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/packages/Cow.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/packages/Cow.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/packages/Cow.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.packages;
+
+class Cow
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/packages/Fox.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/packages/Fox.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/packages/Fox.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.packages;
+
+class Fox
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/subpackages/Cow.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/subpackages/Cow.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/subpackages/Cow.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.subpackages;
+
+class Cow
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/subpackages/SubpackagesArtifactTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/subpackages/SubpackagesArtifactTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/subpackages/SubpackagesArtifactTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,46 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.subpackages;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+import org.jboss.testharness.impl.packaging.ArtifactDescriptor;
+import org.jboss.testharness.test.impl.packaging.AbstractArtifactTest;
+import org.testng.annotations.Test;
+
+public class SubpackagesArtifactTest extends AbstractArtifactTest
+{  
+   
+   @Test
+   public void testAllClassesInPackageAndNotSubPackages() throws Exception
+   {
+      ArtifactDescriptor artifactDescriptor = new ArtifactDescriptor(null);
+      artifactDescriptor.addPackage(SubpackagesArtifactTest.class.getPackage());
+      File root = artifactDescriptor.getExplodedJar();
+      File currentPackage = getCurrentPackageAsFile(root);
+      assert currentPackage.listFiles().length == 4;
+      File[] cowClasses = currentPackage.listFiles(new FilenameFilter()
+      {
+         
+         public boolean accept(File dir, String name)
+         {
+            return name.equals("Cow.class");
+         }
+         
+      });
+      assert cowClasses.length == 1;
+      assert cowClasses[0].getName().equals("Cow.class");
+      assert cowClasses[0].isFile();
+      
+      File[] testClasses = currentPackage.listFiles(new FilenameFilter()
+      {
+         
+         public boolean accept(File dir, String name)
+         {
+            return name.startsWith("SubpackagesArtifactTest");
+         }
+         
+      });
+      assert testClasses.length == 3;
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/subpackages/subpackge/Fox.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/subpackages/subpackge/Fox.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/subpackages/subpackge/Fox.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.subpackages.subpackge;
+
+class Fox
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/tck/Cow.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/tck/Cow.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/tck/Cow.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.tck;
+
+class Cow
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/tck/DummyTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/tck/DummyTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/tck/DummyTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.tck;
+
+public class DummyTest
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/tck/TCKArtifactTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/tck/TCKArtifactTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/tck/TCKArtifactTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,44 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.tck;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import org.jboss.testharness.impl.packaging.ArtifactDescriptor;
+import org.jboss.testharness.impl.packaging.war.WarArtifactDescriptor;
+import org.jboss.testharness.test.impl.packaging.AbstractArtifactTest;
+import org.testng.annotations.Test;
+
+public class TCKArtifactTest extends AbstractArtifactTest
+{  
+   
+   @Test
+   public void testTCKSupportJar() throws Exception
+   {
+      ArtifactDescriptor artifactDescriptor = new WarArtifactDescriptor(DummyTest.class, null);
+      File root = artifactDescriptor.getExplodedJar();
+      File tckSupportJar = new File(root, "WEB-INF/lib/tck-support.jar");
+      assert tckSupportJar.exists();
+      assert tckSupportJar.isFile();
+      assert tckSupportJar.length() > 0;
+      JarInputStream is = new JarInputStream(new FileInputStream(tckSupportJar));
+      JarEntry entry;
+      List<String> fileNames = new ArrayList<String>();
+      while ((entry = is.getNextJarEntry()) != null)
+      {
+         fileNames.add(entry.getName().replace(File.separator, "/"));
+      }
+      assert fileNames.contains("org/jboss/testharness/impl/util/Reflections.class");
+      assert fileNames.contains("org/jboss/testharness/AbstractTest.class");
+      assert fileNames.contains("org/jboss/testharness/impl/TCKImpl.class");
+      assert fileNames.contains("org/jboss/testharness/impl/packaging/ArtifactDescriptor.class");
+      assert fileNames.contains("org/jboss/testharness/impl/packaging/jsr299/TCKArtifactDescriptor.class");
+      assert fileNames.contains("org/jboss/testharness/impl/packaging/war/WarArtifactDescriptor.class");
+      assert fileNames.contains("org/jboss/testharness/impl/runner/TestRunner.class");
+      assert fileNames.contains("org/jboss/testharness/impl/runner/servlet/ServletTestRunner.class");
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/war/Cow.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/war/Cow.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/war/Cow.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.war;
+
+class Cow
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/war/DummyTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/war/DummyTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/war/DummyTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.war;
+
+public class DummyTest
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/war/WarArtifactTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/war/WarArtifactTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/descriptors/war/WarArtifactTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,101 @@
+package org.jboss.testharness.test.impl.packaging.descriptors.war;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import org.jboss.testharness.AbstractTest;
+import org.jboss.testharness.impl.packaging.war.WarArtifactDescriptor;
+import org.jboss.testharness.test.impl.packaging.AbstractArtifactTest;
+import org.testng.annotations.Test;
+
+public class WarArtifactTest extends AbstractArtifactTest
+{
+   @Test
+   public void testDefaultWar() throws Exception
+   {
+      WarArtifactDescriptor war = new WarArtifactDescriptor(DummyTest.class, null);
+      war.getClasses().add(Cow.class);
+      File root = war.getExplodedJar();
+      assert root.listFiles().length == 1;
+      assert root.isDirectory();
+      assert root.listFiles(WEB_INF_FILTER).length == 1;
+      File webInf = root.listFiles(WEB_INF_FILTER)[0];
+      assert webInf.getName().equals("WEB-INF");
+      assert webInf.isDirectory();
+      assert webInf.listFiles().length == 4;
+      assert webInf.listFiles(WEB_XML_FILTER).length == 1;
+      File webXml = webInf.listFiles(WEB_XML_FILTER)[0];
+      assert webXml.isFile();
+      assert webXml.getName().equals("web.xml");
+      assert webXml.length() != 0;
+      File beansXml = webInf.listFiles(BEANS_XML_FILTER)[0];
+      assert beansXml.isFile();
+      assert beansXml.getName().equals("beans.xml");
+      assert beansXml.length() == 0;
+      File currentPackage = getCurrentPackageAsFile(root);
+      File[] cowClasses = currentPackage.listFiles(new FilenameFilter()
+      {
+         
+         public boolean accept(File dir, String name)
+         {
+            return name.equals("Cow.class");
+         }
+         
+      });
+      assert cowClasses.length == 1;
+      assert cowClasses[0].getName().equals("Cow.class");
+      assert cowClasses[0].isFile();
+      File tckPackage = getPackageAsFile(AbstractTest.class.getPackage(), root);
+      File[] abstractTestClasses = tckPackage.listFiles(new FilenameFilter()
+      {
+         
+         public boolean accept(File dir, String name)
+         {
+            return name.equals("AbstractTest.class");
+         }
+         
+      });
+      File webInfLib = new File(webInf, "lib");
+      assert webInfLib.isDirectory();
+      assert webInfLib.list().length == 3;
+      List<String> libs = Arrays.asList(webInfLib.list());
+      assert libs.contains("jboss-test-harness-api.jar");
+      assert libs.contains("testng.jar");
+      assert libs.contains("tck-support.jar");
+   }
+   
+   
+   @Test
+   public void testJarProduction() throws Exception
+   {
+      WarArtifactDescriptor war = new WarArtifactDescriptor(DummyTest.class, null);
+      war.getClasses().add(Cow.class);
+      JarInputStream is = new JarInputStream(war.getJarAsStream());
+      JarEntry entry;
+      List<String> fileNames = new ArrayList<String>();
+      while ((entry = is.getNextJarEntry()) != null)
+      {
+         fileNames.add(entry.getName().replace(File.separator, "/"));
+      }
+      is.close();
+      assert fileNames.contains("WEB-INF/beans.xml");
+      assert fileNames.contains("WEB-INF/web.xml");
+      assert fileNames.contains("WEB-INF/classes/org/jboss/testharness/test/impl/packaging/descriptors/war/Cow.class");
+      assert fileNames.contains("WEB-INF/lib/tck-support.jar");
+   }
+   
+   @Override
+   protected File getPackageAsFile(Package pkg, File root)
+   {
+      root = root.listFiles(WEB_INF_FILTER)[0];
+      root = root.listFiles(CLASSES_FILTER)[0];
+      return super.getPackageAsFile(pkg, root);
+   }
+   
+}
+

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/ArtifactScannerTest.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/ArtifactScannerTest.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/ArtifactScannerTest.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,54 @@
+package org.jboss.testharness.test.impl.packaging.scanner;
+
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.testharness.api.Configuration;
+import org.jboss.testharness.impl.packaging.ArtifactDescriptor;
+import org.jboss.testharness.impl.packaging.ArtifactGenerator;
+import org.jboss.testharness.impl.packaging.ArtifactScanner;
+import org.jboss.testharness.test.impl.mock.MockConfiguration;
+import org.jboss.testharness.test.impl.packaging.scanner.subpackage.AnotherDummyArtifact;
+import org.jboss.testharness.test.impl.packaging.scanner.subpackage.NotAnArtifact;
+import org.testng.annotations.Test;
+
+public class ArtifactScannerTest
+{
+   
+   @Test
+   public void testScanner()
+   {
+      ArtifactScanner scanner = new ArtifactScanner(ArtifactScannerTest.class.getPackage().getName(), null);
+      Set<Class<?>> classes = scanner.getClasses();
+      assert classes.contains(DummyArtifact.class);
+      assert classes.contains(AnotherDummyArtifact.class);
+      assert !classes.contains(NotAnArtifact.class);
+   }
+   
+   @Test
+   public void testMockArtifactGenerator() throws Exception
+   {
+      Configuration configuration = new MockConfiguration();
+      ArtifactGenerator generator = new ArtifactGenerator(configuration);
+      List<ArtifactDescriptor> artifacts = generator.createArtifacts(DummyArtifact.class.getPackage().getName());
+      assert artifacts.size() == 2;
+      for (ArtifactDescriptor artifact : artifacts)
+      {
+         if (artifact.getDeclaringClass().equals(DummyArtifact.class))
+         {
+            assert artifact.getClasses().contains(ArtifactScannerTest.class);
+            assert artifact.getClasses().contains(DummyArtifact.class);
+            assert !artifact.getClasses().contains(AnotherDummyArtifact.class);
+            assert !artifact.getClasses().contains(NotAnArtifact.class);
+         }
+         if (artifact.getDeclaringClass().equals(AnotherDummyArtifact.class))
+         {
+            assert !artifact.getClasses().contains(ArtifactScannerTest.class);
+            assert !artifact.getClasses().contains(DummyArtifact.class);
+            assert artifact.getClasses().contains(AnotherDummyArtifact.class);
+            assert artifact.getClasses().contains(NotAnArtifact.class); 
+         }
+      }
+   }
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/DummyArtifact.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/DummyArtifact.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/DummyArtifact.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,9 @@
+package org.jboss.testharness.test.impl.packaging.scanner;
+
+import org.jboss.testharness.impl.packaging.Artifact;
+
+ at Artifact
+public class DummyArtifact
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/subpackage/AnotherDummyArtifact.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/subpackage/AnotherDummyArtifact.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/subpackage/AnotherDummyArtifact.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,9 @@
+package org.jboss.testharness.test.impl.packaging.scanner.subpackage;
+
+import org.jboss.testharness.impl.packaging.Artifact;
+
+ at Artifact
+public class AnotherDummyArtifact
+{
+   
+}

Added: test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/subpackage/NotAnArtifact.java
===================================================================
--- test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/subpackage/NotAnArtifact.java	                        (rev 0)
+++ test-harness/trunk/impl/src/test/java/org/jboss/testharness/test/impl/packaging/scanner/subpackage/NotAnArtifact.java	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,6 @@
+package org.jboss.testharness.test.impl.packaging.scanner.subpackage;
+
+public class NotAnArtifact
+{
+   
+}

Added: test-harness/trunk/impl/src/test/resources/org/jboss/testharness/impl/packaging/ear/ejb-jar.xml
===================================================================
--- test-harness/trunk/impl/src/test/resources/org/jboss/testharness/impl/packaging/ear/ejb-jar.xml	                        (rev 0)
+++ test-harness/trunk/impl/src/test/resources/org/jboss/testharness/impl/packaging/ear/ejb-jar.xml	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" 
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
+         version="3.0">
+   
+</ejb-jar>

Added: test-harness/trunk/impl/src/test/resources/org/jboss/testharness/impl/packaging/jsr299/default/beans.xml
===================================================================

Added: test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarative/standalone/foo/foo.xml
===================================================================

Added: test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarative/standalone/my-web-beans.xml
===================================================================
--- test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarative/standalone/my-web-beans.xml	                        (rev 0)
+++ test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarative/standalone/my-web-beans.xml	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1 @@
+<my></my>
\ No newline at end of file

Added: test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarative/war/my-web.xml
===================================================================
--- test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarative/war/my-web.xml	                        (rev 0)
+++ test-harness/trunk/impl/src/test/resources/org/jboss/testharness/test/impl/packaging/declarative/war/my-web.xml	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1 @@
+<web></web>
\ No newline at end of file

Added: test-harness/trunk/pom.xml
===================================================================
--- test-harness/trunk/pom.xml	                        (rev 0)
+++ test-harness/trunk/pom.xml	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,297 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+   <modelVersion>4.0.0</modelVersion>
+   <groupId>org.jboss.test-harness</groupId>
+   <artifactId>jboss-test-harness-parent</artifactId>
+   <packaging>pom</packaging>
+   <version>1.0.0-SNAPSHOT</version>
+   <name>JBoss Test Harness Aggregator</name>
+   <url>http://www.seamframework.org/WebBeans</url>
+
+   <developers>
+      <developer>
+         <name>Pete Muir</name>
+         <email>pete.muir at jboss.org</email>
+         <organization>JBoss, a division of Red Hat</organization>
+         <url>http://in.relation.to/Bloggers/Pete</url>
+      </developer>
+
+   </developers>
+
+   <repositories>
+      <repository>
+         <id>repository.jboss.org</id>
+         <name>JBoss Repository</name>
+         <url>http://repository.jboss.org/maven2</url>
+      </repository>
+      <repository>
+         <id>snapshots.jboss.org</id>
+         <name>JBoss Repository</name>
+         <url>http://snapshots.jboss.org/maven2</url>
+      </repository>
+   </repositories>
+
+   <pluginRepositories>
+      <pluginRepository>
+         <id>repository.jboss.org</id>
+         <name>JBoss Repository</name>
+         <url>http://repository.jboss.org/maven2</url>
+      </pluginRepository>
+   </pluginRepositories>
+
+   <modules>
+      <module>api</module>
+      <module>impl</module>
+   </modules>
+
+   <dependencyManagement>
+      <dependencies>
+
+         <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>5.8</version>
+            <classifier>jdk15</classifier>
+         </dependency>
+         
+         <dependency>
+            <groupId>org.jboss.test-harness</groupId>
+            <artifactId>jboss-test-harness-api</artifactId>
+            <version>${project.version}</version>
+         </dependency>
+         
+         <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.14</version>
+         </dependency>
+         
+         <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.5</version>
+         </dependency>
+
+      </dependencies>
+   </dependencyManagement>
+
+   <build>
+      <defaultGoal>install</defaultGoal>
+      <extensions>
+         <extension>
+            <groupId>org.apache.maven.wagon</groupId>
+            <artifactId>wagon-webdav</artifactId>
+            <version>1.0-beta-2</version>
+         </extension>
+      </extensions>
+      <plugins>
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-source-plugin</artifactId>
+            <executions>
+               <execution>
+                  <id>attach-sources</id>
+                  <phase>verify</phase>
+                  <goals>
+                     <goal>jar</goal>
+                  </goals>
+               </execution>
+            </executions>
+         </plugin>
+         <plugin>
+           <groupId>org.apache.maven.plugins</groupId>
+           <artifactId>maven-release-plugin</artifactId>
+           <configuration>
+             <tagBase>https://svn.jboss.org/repos/webbeans/test-harness/tags</tagBase>
+             <autoVersionSubmodules>true</autoVersionSubmodules>
+             <allowTimestampedSnapshots>true</allowTimestampedSnapshots>
+           </configuration>
+         </plugin>
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-enforcer-plugin</artifactId>
+         </plugin>   
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-assembly-plugin</artifactId>
+            <configuration>
+               <descriptors>
+                  <descriptor>src/main/assembly/assembly.xml</descriptor>
+               </descriptors>
+            </configuration>
+         </plugin>
+      </plugins>
+      <pluginManagement>
+         <plugins>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-compiler-plugin</artifactId>
+               <version>2.0.2</version>
+               <configuration>
+                  <source>1.5</source>
+                  <target>1.5</target>
+               </configuration>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-jar-plugin</artifactId>
+               <configuration>
+                  <archive>
+                     <manifest>
+                        <addDefaultImplementationEntries>
+                           true
+                        </addDefaultImplementationEntries>
+                        <addDefaultSpecificationEntries>
+                           true
+                        </addDefaultSpecificationEntries>
+                     </manifest>
+                  </archive>
+               </configuration>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-surefire-report-plugin</artifactId>
+               <version>2.4.3</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-surefire-plugin</artifactId>
+               <version>2.4.3</version>
+            </plugin>
+            <plugin>
+               <groupId>org.codehaus.mojo</groupId>
+               <artifactId>properties-maven-plugin</artifactId>
+               <version>1.0-alpha-1</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-clean-plugin</artifactId>
+               <version>2.2</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-deploy-plugin</artifactId>
+               <version>2.4</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-install-plugin</artifactId>
+               <version>2.2</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-site-plugin</artifactId>
+               <version>2.0-beta-6</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-source-plugin</artifactId>
+               <version>2.0.4</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-resources-plugin</artifactId>
+               <version>2.2</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-jar-plugin</artifactId>
+               <version>2.2</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-dependency-plugin</artifactId>
+               <version>2.0</version>
+            </plugin>
+            <plugin>
+               <groupId>org.codehaus.mojo</groupId>
+               <artifactId>exec-maven-plugin</artifactId>
+               <version>1.1</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-javadoc-plugin</artifactId>
+               <version>2.4</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-assembly-plugin</artifactId>
+               <version>2.2-beta-2</version>
+            </plugin>            
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-enforcer-plugin</artifactId>
+               <version>1.0-alpha-4</version>
+               <executions>
+                  <execution>
+                     <id>enforce</id>
+                     <goals>
+                        <goal>enforce</goal>
+                     </goals>
+                     <configuration>
+                        <rules>
+                           <requireMavenVersion>
+                              <version>2.0.9</version>
+                           </requireMavenVersion>
+                           <requirePluginVersions>
+                              <unCheckedPlugins>
+                                 <unCheckedPlugin>org.apache.maven.plugins:maven-eclipse-plugin</unCheckedPlugin>
+                              </unCheckedPlugins>
+                           </requirePluginVersions>
+                        </rules>
+                     </configuration>
+                  </execution>
+               </executions>
+            </plugin>
+               <plugin>
+                  <groupId>org.apache.maven.plugins</groupId>
+                  <artifactId>maven-release-plugin</artifactId>
+                  <version>2.0-beta-8</version>
+               </plugin>
+         </plugins>
+      </pluginManagement>
+   </build>
+   
+   <ciManagement>
+      <system>Hudson</system>
+      <url />
+   </ciManagement>
+
+   <issueManagement>
+      <system>JIRA</system>
+      <url>http://jira.jboss.org/browse/WBTCK</url>
+   </issueManagement>
+
+   <inceptionYear>2009</inceptionYear>
+
+   <licenses>
+      <license>
+         <name>Apache License, Version 2.0</name>
+         <url>http://www.apache.org/licenses/LICENSE-2.0</url>
+      </license>
+   </licenses>
+
+   <scm>
+      <connection>scm:svn:http://anonsvn.jboss.org/repos/webbeans/test-harness</connection>
+      <developerConnection>
+         scm:svn:https://svn.jboss.org/repos/webbeans/test-harness
+      </developerConnection>
+      <url>http://fisheye.jboss.org/browse/WebBeans</url>
+   </scm>
+
+   <distributionManagement>
+      <repository>
+         <!-- Copy the dist to the local checkout of the JBoss maven2 repo ${maven.repository.root} -->
+         <!-- It is anticipated that ${maven.repository.root} be set in user's settings.xml -->
+         <!-- todo : replace this with direct svn access once the svnkit providers are available -->
+         <id>repository.jboss.org</id>
+         <url>file://${maven.repository.root}</url>
+      </repository>
+      <snapshotRepository>
+         <id>snapshots.jboss.org</id>
+         <name>JBoss Snapshot Repository</name>
+         <url>dav:https://snapshots.jboss.org/maven2</url>
+      </snapshotRepository>
+   </distributionManagement>
+   
+</project>

Added: test-harness/trunk/readme.txt
===================================================================
--- test-harness/trunk/readme.txt	                        (rev 0)
+++ test-harness/trunk/readme.txt	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,17 @@
+JSR-299 TCK harness
+------------
+
+Java Contexts and Dependency Injection (JSR-299) is a new Java standard for
+dependency injection and contextual lifecycle management. This is the TCK test harness for
+JSR-299
+
+This distribution, as a whole, is licensed under the terms of the Apache Public
+License (see apl.txt).
+
+Documentation can be found at http://seamframework.org/WebBeans/JSR299TCK
+
+This distribution consists of:
+
+src/
+   -- TCK harness sources 
+

Added: test-harness/trunk/src/main/assembly/assembly.xml
===================================================================
--- test-harness/trunk/src/main/assembly/assembly.xml	                        (rev 0)
+++ test-harness/trunk/src/main/assembly/assembly.xml	2009-03-10 13:34:37 UTC (rev 1903)
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<assembly xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="
+              http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd
+          ">
+   <id>dist</id>
+   <baseDirectory>jsr299-tck-${project.version}</baseDirectory>
+   <formats>
+      <format>zip</format>
+   </formats>
+   <fileSets>
+      <fileSet>
+         <directory>${project.basedir}</directory>
+         <outputDirectory>src</outputDirectory>
+         <includes>
+            <include>**/pom.xml</include>
+            <include>**/src/**</include>
+         </includes>
+         <excludes>
+            <exclude>**/src/main/assembly/**</exclude>
+            <exclude>**/bin/**</exclude>
+         </excludes>
+         <useDefaultExcludes />
+      </fileSet>
+      <fileSet>
+         <directory>${project.basedir}/impl/src/main/resources</directory>
+         <outputDirectory>lib</outputDirectory>
+         <includes>
+            <include>tck-tests.xml</include>
+         </includes>
+      </fileSet>
+      <fileSet>
+         <directory>${project.basedir}</directory>
+         <outputDirectory>/</outputDirectory>
+         <includes>
+            <include>readme.txt</include>
+            <include>apl.txt</include>
+         </includes>
+      </fileSet>
+   </fileSets>
+
+   <moduleSets>
+      <moduleSet>
+         <includes>
+            <include>org.jboss.jsr299.tck:jsr299-tck-impl</include>
+         </includes>
+         <binaries>
+            <outputDirectory>lib</outputDirectory>
+            <unpack>false</unpack>
+         </binaries>
+      </moduleSet>
+   </moduleSets>
+
+
+</assembly>




More information about the weld-commits mailing list