diff --git a/sandbox/itest/pom.xml b/sandbox/itest/pom.xml
new file mode 100644
index 0000000000..89b8f18321
--- /dev/null
+++ b/sandbox/itest/pom.xml
@@ -0,0 +1,172 @@
+
+ 4.0.0
+
+ org.springframework.security
+ spring-security-itest
+ Spring Security - Integration Tests
+ pom
+ 2.0.3-SNAPSHOT
+
+ web
+
+
+
+
+ org.testng
+ testng
+ 5.8
+ test
+ jdk15
+
+
+
+ org.springframework
+ spring
+ 2.5.4
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+ org.springframework.security
+ spring-security-core
+ ${project.version}
+
+
+ org.springframework
+ spring-core
+
+
+ org.springframework
+ spring-context
+
+
+ org.springframework
+ spring-aop
+
+
+ org.springframework
+ spring-support
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+ org.springframework.security
+ spring-security-core-tiger
+ ${project.version}
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+ org.slf4j
+ slf4j-api
+ 1.4.3
+ runtime
+
+
+ org.apache.directory.server
+ apacheds-core
+ 1.0.2
+ runtime
+
+
+ org.apache.directory.server
+ apacheds-server-jndi
+ 1.0.2
+ runtime
+
+
+ org.springframework.ldap
+ spring-ldap
+ 1.2.1
+ runtime
+
+
+ org.springframework
+ spring-core
+
+
+ org.springframework
+ spring-beans
+
+
+
+
+ org.slf4j
+ slf4j-log4j12
+ 1.4.3
+ runtime
+
+
+ org.slf4j
+ jcl104-over-slf4j
+ 1.4.3
+ provided
+
+
+ log4j
+ log4j
+ 1.2.13
+ runtime
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.5
+ 1.5
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.4.2
+
+
+ **/*Tests.class
+
+
+ **/Abstract*
+
+ once
+
+
+
+ apacheDSWorkDir
+
+ ${basedir}/target/apacheds-work
+
+
+
+
+
+
+
+
diff --git a/sandbox/itest/web/pom.xml b/sandbox/itest/web/pom.xml
new file mode 100644
index 0000000000..31cb2b130b
--- /dev/null
+++ b/sandbox/itest/web/pom.xml
@@ -0,0 +1,43 @@
+
+
+ 4.0.0
+
+ org.springframework.security
+ spring-security-itest
+ 2.0.3-SNAPSHOT
+
+ spring-security-itest-web
+ Spring Security - Web Integration Tests
+ war
+
+
+
+ jwebunit
+ jwebunit
+ 1.2
+ test
+
+
+ org.mortbay.jetty
+ jetty
+ ${jetty.version}
+ test
+
+
+ org.mortbay.jetty
+ jetty-naming
+ ${jetty.version}
+ test
+
+
+ org.mortbay.jetty
+ jetty-plus
+ ${jetty.version}
+ test
+
+
+
+ 6.1.7
+
+
diff --git a/sandbox/itest/web/src/main/resources/log4j.properties b/sandbox/itest/web/src/main/resources/log4j.properties
new file mode 100644
index 0000000000..e5340c70b2
--- /dev/null
+++ b/sandbox/itest/web/src/main/resources/log4j.properties
@@ -0,0 +1,8 @@
+log4j.rootCategory=INFO, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %p %c - %m%n
+
+log4j.category.org.mortbay.log=INFO
+log4j.category.org.springframework.security=DEBUG
\ No newline at end of file
diff --git a/sandbox/itest/web/src/main/resources/test-server.ldif b/sandbox/itest/web/src/main/resources/test-server.ldif
new file mode 100644
index 0000000000..f2caf17ca8
--- /dev/null
+++ b/sandbox/itest/web/src/main/resources/test-server.ldif
@@ -0,0 +1,56 @@
+dn: ou=groups,dc=springframework,dc=org
+objectclass: top
+objectclass: organizationalUnit
+ou: groups
+
+dn: ou=subgroups,ou=groups,dc=springframework,dc=org
+objectclass: top
+objectclass: organizationalUnit
+ou: subgroups
+
+dn: ou=people,dc=springframework,dc=org
+objectclass: top
+objectclass: organizationalUnit
+ou: people
+
+dn: uid=ben,ou=people,dc=springframework,dc=org
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+cn: Ben Alex
+sn: Alex
+uid: ben
+userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=
+
+dn: uid=bob,ou=people,dc=springframework,dc=org
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+cn: Bob Hamilton
+sn: Hamilton
+uid: bob
+userPassword: bobspassword
+
+dn: cn=developers,ou=groups,dc=springframework,dc=org
+objectclass: top
+objectclass: groupOfNames
+cn: developers
+ou: developer
+member: uid=ben,ou=people,dc=springframework,dc=org
+member: uid=bob,ou=people,dc=springframework,dc=org
+
+dn: cn=managers,ou=groups,dc=springframework,dc=org
+objectclass: top
+objectclass: groupOfNames
+cn: managers
+ou: manager
+member: uid=ben,ou=people,dc=springframework,dc=org
+
+dn: cn=submanagers,ou=subgroups,ou=groups,dc=springframework,dc=org
+objectclass: top
+objectclass: groupOfNames
+cn: submanagers
+ou: submanager
+member: uid=ben,ou=people,dc=springframework,dc=org
diff --git a/sandbox/itest/web/src/main/webapp/META-INF/MANIFEST.MF b/sandbox/itest/web/src/main/webapp/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..5e9495128c
--- /dev/null
+++ b/sandbox/itest/web/src/main/webapp/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
diff --git a/sandbox/itest/web/src/main/webapp/WEB-INF/http-security.xml b/sandbox/itest/web/src/main/webapp/WEB-INF/http-security.xml
new file mode 100644
index 0000000000..4e92b39a99
--- /dev/null
+++ b/sandbox/itest/web/src/main/webapp/WEB-INF/http-security.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/itest/web/src/main/webapp/WEB-INF/ldap-provider.xml b/sandbox/itest/web/src/main/webapp/WEB-INF/ldap-provider.xml
new file mode 100644
index 0000000000..0156db26b8
--- /dev/null
+++ b/sandbox/itest/web/src/main/webapp/WEB-INF/ldap-provider.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/itest/web/src/main/webapp/WEB-INF/web.xml b/sandbox/itest/web/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..1aa6ef9011
--- /dev/null
+++ b/sandbox/itest/web/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,20 @@
+
+
+
+ Integration Tests Webapp
+
+
+ springSecurityFilterChain
+ org.springframework.web.filter.DelegatingFilterProxy
+
+
+
+ springSecurityFilterChain
+ /*
+
+
+
+
+
diff --git a/sandbox/itest/web/src/main/webapp/secure/index.html b/sandbox/itest/web/src/main/webapp/secure/index.html
new file mode 100644
index 0000000000..a74431b097
--- /dev/null
+++ b/sandbox/itest/web/src/main/webapp/secure/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+ A secure page
+
+
+ A Secure Page.
+
+
\ No newline at end of file
diff --git a/sandbox/itest/web/src/test/java/org/springframework/security/integration/AbstractWebLoginTests.java b/sandbox/itest/web/src/test/java/org/springframework/security/integration/AbstractWebLoginTests.java
new file mode 100644
index 0000000000..ebb31bdcbe
--- /dev/null
+++ b/sandbox/itest/web/src/test/java/org/springframework/security/integration/AbstractWebLoginTests.java
@@ -0,0 +1,31 @@
+package org.springframework.security.integration;
+
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Luke Taylor
+ * @version $Id$
+ */
+public abstract class AbstractWebLoginTests extends AbstractWebServerIntegrationTests {
+
+ @Test
+ public void loginFailsWithinvalidPassword() {
+ beginAt("secure/index.html");
+ assertFormPresent();
+ setFormElement("j_username", "bob");
+ setFormElement("j_password", "wrongpassword");
+ submit();
+ assertTextPresent("Your login attempt was not successful");
+ }
+
+ @Test
+ public void loginSucceedsWithCorrectPassword() {
+ beginAt("secure/index.html");
+ assertFormPresent();
+ setFormElement("j_username", "bob");
+ setFormElement("j_password", "bobspassword");
+ submit();
+ assertTextPresent("A Secure Page");
+ }
+}
diff --git a/sandbox/itest/web/src/test/java/org/springframework/security/integration/AbstractWebServerIntegrationTests.java b/sandbox/itest/web/src/test/java/org/springframework/security/integration/AbstractWebServerIntegrationTests.java
new file mode 100644
index 0000000000..ebbc1883af
--- /dev/null
+++ b/sandbox/itest/web/src/test/java/org/springframework/security/integration/AbstractWebServerIntegrationTests.java
@@ -0,0 +1,95 @@
+package org.springframework.security.integration;
+
+import org.springframework.web.context.ContextLoaderListener;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+import net.sourceforge.jwebunit.WebTester;
+
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.webapp.WebAppContext;
+
+import javax.servlet.ServletContext;
+
+import org.testng.annotations.*;
+
+/**
+ * @author Luke Taylor
+ * @version $Id$
+ */
+public abstract class AbstractWebServerIntegrationTests {
+ private Server server;
+ private final Object SERVER_LOCK = new Object();
+ protected final WebTester tester = new WebTester();;
+
+ /** Override to set the application context files that should be loaded */
+ protected abstract String getContextConfigLocations();
+
+ protected String getContextPath() {
+ return "/testapp";
+ }
+
+ @BeforeClass
+ public void startServer() throws Exception {
+ synchronized(SERVER_LOCK) {
+ if (server == null) {
+ server = new Server(0);
+ WebAppContext webCtx = new WebAppContext("src/main/webapp", getContextPath());
+
+ webCtx.addEventListener(new ContextLoaderListener());
+ webCtx.getInitParams().put("contextConfigLocation", getContextConfigLocations());
+
+ server.addHandler(webCtx);
+ server.start();
+
+ tester.getTestContext().setBaseUrl(getBaseUrl());
+ }
+ }
+ }
+
+ @AfterClass
+ public void stopServer() throws Exception {
+ synchronized(SERVER_LOCK) {
+ if (server != null) {
+ server.stop();
+ }
+ server = null;
+ }
+ }
+
+ protected final String getBaseUrl() {
+ int port = server.getConnectors()[0].getLocalPort();
+ return "http://localhost:" + port + getContextPath() + "/";
+ }
+
+ protected final Object getBean(String beanName) {
+ return getAppContext().getBean(beanName);
+ }
+
+ private WebApplicationContext getAppContext() {
+ ServletContext servletCtx = ((WebAppContext)server.getHandler()).getServletContext();
+ WebApplicationContext appCtx =
+ WebApplicationContextUtils.getRequiredWebApplicationContext(servletCtx);
+ return appCtx;
+ }
+
+ protected final void submit() {
+ tester.submit();
+ }
+
+ protected final void beginAt(String url) {
+ tester.beginAt(url);
+ }
+
+ protected final void setFormElement(String name, String value) {
+ tester.setFormElement(name, value);
+ }
+
+ protected final void assertFormPresent() {
+ tester.assertFormPresent();
+ }
+
+ protected final void assertTextPresent(String text) {
+ tester.assertTextPresent(text);
+ }
+}
diff --git a/sandbox/itest/web/src/test/java/org/springframework/security/integration/LdapWebLoginTests.java b/sandbox/itest/web/src/test/java/org/springframework/security/integration/LdapWebLoginTests.java
new file mode 100644
index 0000000000..56bce730f2
--- /dev/null
+++ b/sandbox/itest/web/src/test/java/org/springframework/security/integration/LdapWebLoginTests.java
@@ -0,0 +1,20 @@
+package org.springframework.security.integration;
+
+import org.testng.annotations.*;
+
+/**
+ * @author Luke Taylor
+ * @version $Id$
+ */
+public class LdapWebLoginTests extends AbstractWebLoginTests {
+
+ protected String getContextConfigLocations() {
+ return "/WEB-INF/http-security.xml /WEB-INF/ldap-provider.xml";
+ }
+
+ @Test
+ public void doSomething() {
+
+ }
+
+}