diff --git a/pom.xml b/pom.xml
index 00d2720e091bd909bd1ed0dd9336827cf77aad08..1cd34c9c595e1f17ba157ce34a26cce1d9f9ed4b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2049,48 +2049,6 @@
 			<version>1.1.1</version>
 			<scope>test</scope>
 		</dependency>
-		<dependency>
-			<groupId>com.sun.jersey</groupId>
-			<artifactId>jersey-server</artifactId>
-			<version>${com.sun.jersey.version}</version>
-			<scope>test</scope>
-			<exclusions>
-				<exclusion>
-					<groupId>org.springframework</groupId>
-					<artifactId>spring-core</artifactId>
-				</exclusion>
-				<exclusion>
-					<groupId>org.springframework</groupId>
-					<artifactId>spring</artifactId>
-				</exclusion>
-				<exclusion>
-					<groupId>org.springframework</groupId>
-					<artifactId>spring-beans</artifactId>
-				</exclusion>
-				<exclusion>
-					<groupId>org.springframework</groupId>
-					<artifactId>spring-context</artifactId>
-				</exclusion>
-				<exclusion>
-					<groupId>org.springframework</groupId>
-					<artifactId>spring-web</artifactId>
-				</exclusion>
-				<exclusion>
-					<groupId>org.springframework</groupId>
-					<artifactId>spring-aop</artifactId>
-				</exclusion>
-				<exclusion>
-					<groupId>org.springframework</groupId>
-					<artifactId>spring-jca</artifactId>
-				</exclusion>
-			</exclusions>
-		</dependency>
-		<dependency>
-			<groupId>com.sun.jersey.jersey-test-framework</groupId>
-			<artifactId>jersey-test-framework-grizzly</artifactId>
-			<version>${com.sun.jersey.version}</version>
-			<scope>test</scope>
-		</dependency>
 
 		<dependency>
 			<groupId>org.codehaus.jackson</groupId>
@@ -2134,6 +2092,18 @@
 			<version>4.8.2</version>
 			<scope>test</scope>
 		</dependency>
+		<dependency>
+		    <groupId>io.undertow</groupId>
+		    <artifactId>undertow-core</artifactId>
+		    <version>1.0.0.Beta21</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+		    <groupId>io.undertow</groupId>
+		    <artifactId>undertow-servlet</artifactId>
+		    <version>1.0.0.Beta21</version>
+			<scope>test</scope>
+		</dependency>
     
 		<!-- Start test dependencies for Arquillian and Selenium -->
     	<dependency>
diff --git a/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResourceRoot.java b/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResourceRoot.java
index dfc61b2c32c847d44d7eeb83ba08e8991eea0081..21cf66cf35eda15f58a97c3b709b19a9ac3e33c3 100644
--- a/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResourceRoot.java
+++ b/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResourceRoot.java
@@ -170,7 +170,7 @@ public class VFSResourceRoot implements WebResourceRoot  {
 	}
 
 	@Override
-	public boolean write(String path, InputStream is, boolean overwrite) {
+	public boolean write(String path, InputStream is, boolean overwrite, WebResource movedFrom) {
 		VFSLeaf childLeaf;
 		VFSItem file = resolveFile(path);
 		if (file instanceof VFSLeaf) {
@@ -235,6 +235,15 @@ public class VFSResourceRoot implements WebResourceRoot  {
 			}
 		}
 		
+		if(movedFrom instanceof VFSResource) {
+			VFSResource vfsResource = (VFSResource)movedFrom;
+			if(vfsResource.getItem() instanceof Versionable
+					&& ((Versionable)vfsResource.getItem()).getVersions().isVersioned()) {
+				VFSLeaf currentVersion = (VFSLeaf)vfsResource.getItem();
+				VersionsManager.getInstance().move(currentVersion, childLeaf, identity);
+			}
+		}
+		
 		return true;
 	}
 	
diff --git a/src/main/java/org/olat/core/commons/services/webdav/servlets/DefaultDispatcher.java b/src/main/java/org/olat/core/commons/services/webdav/servlets/DefaultDispatcher.java
index 67a6bbb0b1deb96b975bb712842ee3f39d45fcd4..30fa8961e2fe91a5f8bca8e2b70516e985ec53e8 100644
--- a/src/main/java/org/olat/core/commons/services/webdav/servlets/DefaultDispatcher.java
+++ b/src/main/java/org/olat/core/commons/services/webdav/servlets/DefaultDispatcher.java
@@ -39,7 +39,6 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
-import org.olat.core.util.WebappHelper;
 import org.olat.core.util.servlets.URLEncoder;
 
 
@@ -365,7 +364,7 @@ public abstract class DefaultDispatcher implements Serializable {
         // Find content type.
         String contentType = resource.getMimeType();
         if (contentType == null) {
-            contentType = WebappHelper.getMimeType(resource.getName());
+            contentType = request.getServletContext().getMimeType(resource.getName());
             resource.setMimeType(contentType);
         }
 
diff --git a/src/main/java/org/olat/core/commons/services/webdav/servlets/WebDAVDispatcherImpl.java b/src/main/java/org/olat/core/commons/services/webdav/servlets/WebDAVDispatcherImpl.java
index 873332b0657d8a1e11f17c00422bad764cdb4c19..b50f6da04146dd4a485f43c3e1177a27330f80ef 100644
--- a/src/main/java/org/olat/core/commons/services/webdav/servlets/WebDAVDispatcherImpl.java
+++ b/src/main/java/org/olat/core/commons/services/webdav/servlets/WebDAVDispatcherImpl.java
@@ -910,7 +910,7 @@ public class WebDAVDispatcherImpl
                 resourceInputStream = req.getInputStream();
             }
 
-            if (resources.write(path, resourceInputStream, true)) {
+            if (resources.write(path, resourceInputStream, true, null)) {
                 if (resource.exists()) {
                     resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
                 } else {
@@ -1000,7 +1000,7 @@ public class WebDAVDispatcherImpl
         String path = getRelativePath(req);
         WebResourceRoot resources = getResources(req);
     	if (resources.canWrite(path)) {
-    		copyResource(req, resp);
+    		copyResource(req, resp, false);
     	} else {
     		resp.sendError(WebdavStatus.SC_FORBIDDEN);
     	}
@@ -1025,7 +1025,7 @@ public class WebDAVDispatcherImpl
             return;
         }
         
-        if (copyResource(req, resp)) {
+        if (copyResource(req, resp, true)) {
             deleteResource(path, req, resp, false);
         }
     }
@@ -1645,7 +1645,7 @@ public class WebDAVDispatcherImpl
      * @param resp Servlet response
      * @return boolean true if the copy is successful
      */
-    private boolean copyResource(HttpServletRequest req, HttpServletResponse resp)
+    private boolean copyResource(HttpServletRequest req, HttpServletResponse resp, boolean moved)
     throws IOException {
 
         // Parsing destination header
@@ -1718,7 +1718,7 @@ public class WebDAVDispatcherImpl
 
         Hashtable<String,Integer> errorList = new Hashtable<String,Integer>();
 
-        boolean result = copyResource(req, errorList, path, destinationPath);
+        boolean result = copyResource(req, errorList, path, destinationPath, moved);
 
         if ((!result) || (!errorList.isEmpty())) {
             if (errorList.size() == 1) {
@@ -1807,7 +1807,7 @@ public class WebDAVDispatcherImpl
      * @param dest Destination path
      */
     private boolean copyResource(HttpServletRequest req, Hashtable<String,Integer> errorList,
-            String source, String dest) {
+            String source, String dest, boolean moved) {
 
         if (log.isDebug()) log.debug("Copy: " + source + " To: " + dest);
         
@@ -1835,10 +1835,11 @@ public class WebDAVDispatcherImpl
                     childSrc += "/";
                 }
                 childSrc += entry.getName();
-                copyResource(req, errorList, childSrc, childDest);
+                copyResource(req, errorList, childSrc, childDest, moved);
             }
         } else if (sourceResource.isFile()) {
-            if (!resources.write(dest, sourceResource.getInputStream(), false)) {
+        	WebResource movedFrom = moved ? sourceResource : null; 
+            if (!resources.write(dest, sourceResource.getInputStream(), false, movedFrom)) {
                 errorList.put(source, new Integer(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
                 return false;
             }
@@ -2111,8 +2112,7 @@ public class WebDAVDispatcherImpl
                 generatedXML.writeProperty
                     ("D", "getcontentlength",
                      String.valueOf(resource.getContentLength()));
-                String contentType = req.getServletContext().getMimeType(
-                        resource.getName());
+                String contentType = req.getServletContext().getMimeType(resource.getName());
                 if (contentType != null) {
                     generatedXML.writeProperty("D", "getcontenttype",
                             contentType);
diff --git a/src/main/java/org/olat/core/commons/services/webdav/servlets/WebResourceRoot.java b/src/main/java/org/olat/core/commons/services/webdav/servlets/WebResourceRoot.java
index 9a700945bb3c5cd3720bcd32638098191cae6cdd..96fa17d96ca1db5b6971f14162e0cf8a3588910e 100644
--- a/src/main/java/org/olat/core/commons/services/webdav/servlets/WebResourceRoot.java
+++ b/src/main/java/org/olat/core/commons/services/webdav/servlets/WebResourceRoot.java
@@ -82,7 +82,7 @@ public interface WebResourceRoot {
      *
      * @return  <code>true</code> if and only if the new Resource is written
      */
-    boolean write(String path, InputStream is, boolean overwrite);
+    boolean write(String path, InputStream is, boolean overwrite, WebResource movedFrom);
     
     public boolean delete(WebResource resourceo);
 
diff --git a/src/main/java/org/olat/core/servlets/OpenOLATServlet.java b/src/main/java/org/olat/core/servlets/OpenOLATServlet.java
index 3597b56b2a1a0de2df90fc4140f7afbc234ab203..251bdfc12e482eae8f81c080b56dce38d50be426 100644
--- a/src/main/java/org/olat/core/servlets/OpenOLATServlet.java
+++ b/src/main/java/org/olat/core/servlets/OpenOLATServlet.java
@@ -178,7 +178,7 @@ public class OpenOLATServlet extends HttpServlet {
 		String subContext = DispatcherModule.getFirstPath(req);
 		if("/".equals(subContext)) {
 			webDAVDispatcher.doRootOptions(req, resp);
-		} else if("webdav".equals(subContext)) {
+		} else if("/webdav".equals(subContext) || "/webdav/".equals(subContext)) {
 			webDAVDispatcher.doWebdavOptions(req, resp);
 		} else {
 			super.doOptions(req, resp);
@@ -252,9 +252,8 @@ public class OpenOLATServlet extends HttpServlet {
 			Dispatcher dispatcher = dispatchers.get(dispatcherName);
 			dispatcher.execute(request, response);
 		} else {
-			String uri = request.getRequestURI();
 			//root -> redirect to dmz
-			if("/".equals(uri)) {
+			if("/".equals(dispatcherName) || "/dmz".equals(dispatcherName)) {
 				String dmzUri = WebappHelper.getServletContextPath() + DispatcherModule.getPathDefault();
 				response.sendRedirect(dmzUri);
 			} else {
diff --git a/src/main/webapp-tomcat/WEB-INF/web.xml b/src/main/webapp-tomcat/WEB-INF/web.xml
index f135f9c9379607f1e5a0205920d32be0dcab8d7d..842a692ca156da1d86eab1f3140567c7b0a7e2f4 100644
--- a/src/main/webapp-tomcat/WEB-INF/web.xml
+++ b/src/main/webapp-tomcat/WEB-INF/web.xml
@@ -32,14 +32,7 @@
     	<param-name>contextInitializerClasses</param-name>
     	<param-value>org.olat.core.CoreSpringInitializer</param-value>
 	</context-param>
-   <!-- 
-	<filter>
-		<filter-name>SpyFilter</filter-name>
-		<filter-class>org.olat.core.servlets.SpyFilter</filter-class>
-	</filter>
-	-->
-	
-	
+
 	<!-- 2. Filters -->
 	<filter>
 		<filter-name>OnyxHttpsFilter</filter-name>
diff --git a/src/test/java/org/olat/core/commons/services/webdav/HttpCopy.java b/src/test/java/org/olat/core/commons/services/webdav/HttpCopy.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ef53479a87e5e1f2bc73be1b78030a45d8863b0
--- /dev/null
+++ b/src/test/java/org/olat/core/commons/services/webdav/HttpCopy.java
@@ -0,0 +1,57 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.core.commons.services.webdav;
+
+import java.net.URI;
+
+import org.apache.http.client.methods.HttpRequestBase;
+
+/**
+ * 
+ * Initial date: 11.11.2013<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class HttpCopy extends HttpRequestBase {
+
+    public final static String METHOD_NAME = "COPY";
+
+    public HttpCopy() {
+        super();
+    }
+
+    public HttpCopy(final URI uri) {
+        super();
+        setURI(uri);
+    }
+
+    /**
+     * @throws IllegalArgumentException if the uri is invalid.
+     */
+    public HttpCopy(final String uri) {
+        super();
+        setURI(URI.create(uri));
+    }
+
+    @Override
+    public String getMethod() {
+        return METHOD_NAME;
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/olat/core/commons/services/webdav/HttpLock.java b/src/test/java/org/olat/core/commons/services/webdav/HttpLock.java
new file mode 100644
index 0000000000000000000000000000000000000000..b17973109454a2a2a6735f102a58d68ed7e2d688
--- /dev/null
+++ b/src/test/java/org/olat/core/commons/services/webdav/HttpLock.java
@@ -0,0 +1,57 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.core.commons.services.webdav;
+
+import java.net.URI;
+
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+
+/**
+ * 
+ * Initial date: 11.11.2013<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class HttpLock extends HttpEntityEnclosingRequestBase {
+
+    public final static String METHOD_NAME = "LOCK";
+
+    public HttpLock() {
+        super();
+    }
+
+    public HttpLock(final URI uri) {
+        super();
+        setURI(uri);
+    }
+
+    /**
+     * @throws IllegalArgumentException if the uri is invalid.
+     */
+    public HttpLock(final String uri) {
+        super();
+        setURI(URI.create(uri));
+    }
+
+    @Override
+    public String getMethod() {
+        return METHOD_NAME;
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/olat/core/commons/services/webdav/HttpMkcol.java b/src/test/java/org/olat/core/commons/services/webdav/HttpMkcol.java
new file mode 100644
index 0000000000000000000000000000000000000000..be8117f19087d9daf67b92dcca581a7e163ea9a5
--- /dev/null
+++ b/src/test/java/org/olat/core/commons/services/webdav/HttpMkcol.java
@@ -0,0 +1,57 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.core.commons.services.webdav;
+
+import java.net.URI;
+
+import org.apache.http.client.methods.HttpRequestBase;
+
+/**
+ * 
+ * Initial date: 11.11.2013<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class HttpMkcol extends HttpRequestBase {
+
+    public final static String METHOD_NAME = "MKCOL";
+
+    public HttpMkcol() {
+        super();
+    }
+
+    public HttpMkcol(final URI uri) {
+        super();
+        setURI(uri);
+    }
+
+    /**
+     * @throws IllegalArgumentException if the uri is invalid.
+     */
+    public HttpMkcol(final String uri) {
+        super();
+        setURI(URI.create(uri));
+    }
+
+    @Override
+    public String getMethod() {
+        return METHOD_NAME;
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/olat/core/commons/services/webdav/HttpMove.java b/src/test/java/org/olat/core/commons/services/webdav/HttpMove.java
new file mode 100644
index 0000000000000000000000000000000000000000..70c6f2d26ef355e70d1f48f8e8d65d49861922da
--- /dev/null
+++ b/src/test/java/org/olat/core/commons/services/webdav/HttpMove.java
@@ -0,0 +1,57 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.core.commons.services.webdav;
+
+import java.net.URI;
+
+import org.apache.http.client.methods.HttpRequestBase;
+
+/**
+ * 
+ * Initial date: 11.11.2013<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class HttpMove extends HttpRequestBase {
+
+    public final static String METHOD_NAME = "MOVE";
+
+    public HttpMove() {
+        super();
+    }
+
+    public HttpMove(final URI uri) {
+        super();
+        setURI(uri);
+    }
+
+    /**
+     * @throws IllegalArgumentException if the uri is invalid.
+     */
+    public HttpMove(final String uri) {
+        super();
+        setURI(URI.create(uri));
+    }
+
+    @Override
+    public String getMethod() {
+        return METHOD_NAME;
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/olat/core/commons/services/webdav/HttpUnlock.java b/src/test/java/org/olat/core/commons/services/webdav/HttpUnlock.java
new file mode 100644
index 0000000000000000000000000000000000000000..619d1254b5a11b9f35fa2c7e0141e560bd96b5ad
--- /dev/null
+++ b/src/test/java/org/olat/core/commons/services/webdav/HttpUnlock.java
@@ -0,0 +1,57 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.core.commons.services.webdav;
+
+import java.net.URI;
+
+import org.apache.http.client.methods.HttpRequestBase;
+
+/**
+ * 
+ * Initial date: 11.11.2013<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class HttpUnlock extends HttpRequestBase {
+
+    public final static String METHOD_NAME = "UNLOCK";
+
+    public HttpUnlock() {
+        super();
+    }
+
+    public HttpUnlock(final URI uri) {
+        super();
+        setURI(uri);
+    }
+
+    /**
+     * @throws IllegalArgumentException if the uri is invalid.
+     */
+    public HttpUnlock(final String uri) {
+        super();
+        setURI(URI.create(uri));
+    }
+
+    @Override
+    public String getMethod() {
+        return METHOD_NAME;
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/olat/core/commons/services/webdav/WebDAVCommandsTest.java b/src/test/java/org/olat/core/commons/services/webdav/WebDAVCommandsTest.java
index 91085ef34ed461ae5ee56ba19686f33b11977d94..75d71d62cb910b5940bd7ad8d95cceb320fee780 100644
--- a/src/test/java/org/olat/core/commons/services/webdav/WebDAVCommandsTest.java
+++ b/src/test/java/org/olat/core/commons/services/webdav/WebDAVCommandsTest.java
@@ -22,6 +22,7 @@ package org.olat.core.commons.services.webdav;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
@@ -33,6 +34,7 @@ import junit.framework.Assert;
 
 import org.apache.http.Header;
 import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpDelete;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpOptions;
 import org.apache.http.client.methods.HttpPut;
@@ -42,8 +44,14 @@ import org.apache.http.util.EntityUtils;
 import org.apache.poi.util.IOUtils;
 import org.junit.Test;
 import org.olat.basesecurity.BaseSecurity;
+import org.olat.core.commons.modules.bc.FolderConfig;
+import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
+import org.olat.core.util.FileUtils;
+import org.olat.core.util.vfs.VFSContainer;
+import org.olat.core.util.vfs.VFSItem;
+import org.olat.core.util.vfs.VFSLeaf;
 import org.olat.course.CourseFactory;
 import org.olat.repository.RepositoryEntry;
 import org.olat.restapi.CoursePublishTest;
@@ -131,6 +139,110 @@ public class WebDAVCommandsTest extends WebDAVTestCase {
 		IOUtils.closeQuietly(conn);
 	}
 	
+	@Test
+	public void testMkcol_public()
+	throws IOException, URISyntaxException {
+		//create a user
+		Identity user = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-2a-" + UUID.randomUUID().toString());
+
+		//create a file
+		String publicPath = FolderConfig.getUserHomes() + "/" + user.getName() + "/public";
+		VFSContainer vfsPublic = new OlatRootFolderImpl(publicPath, null);
+		Assert.assertTrue(vfsPublic.exists());
+
+		
+		WebDAVConnection conn = new WebDAVConnection();
+		conn.setCredentials(user.getName(), "A6B7C8");
+
+		//author check course folder
+		URI publicUri = conn.getBaseURI().path("webdav").path("home").path("public").build();
+		String publicXml = conn.propfind(publicUri, 2);
+		Assert.assertTrue(publicXml.indexOf("<D:href>/webdav/home/public/</D:href>") > 0);
+
+		//make a folder
+		URI newUri = UriBuilder.fromUri(publicUri).path("newFolder").build();
+		int returnMkcol = conn.mkcol(newUri);
+		Assert.assertEquals(201, returnMkcol);
+		
+		//check if folder exists
+		VFSItem newItem = vfsPublic.resolve("newFolder");
+		Assert.assertNotNull(newItem);
+		Assert.assertTrue(newItem instanceof VFSContainer);
+		Assert.assertTrue(newItem.exists());
+	
+		IOUtils.closeQuietly(conn);
+	}
+	
+	@Test
+	public void testMove_public()
+	throws IOException, URISyntaxException {
+		//create a user
+		Identity user = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-2b-" + UUID.randomUUID().toString());
+
+		//create a file
+		String publicPath = FolderConfig.getUserHomes() + "/" + user.getName() + "/public";
+		VFSContainer vfsPublic = new OlatRootFolderImpl(publicPath, null);
+		createFile(vfsPublic, "test.txt");
+		VFSContainer subPublic = vfsPublic.createChildContainer("moveto");
+
+		WebDAVConnection conn = new WebDAVConnection();
+		conn.setCredentials(user.getName(), "A6B7C8");
+
+		//author check course folder
+		URI publicUri = conn.getBaseURI().path("webdav").path("home").path("public").build();
+		URI fileUri = UriBuilder.fromUri(publicUri).path("test.txt").build();
+		String destination = UriBuilder.fromUri(publicUri).path("moveto").path("test.txt").build().toString();
+		int returnMove = conn.move(fileUri, destination);
+		Assert.assertEquals(201, returnMove);
+
+		//check move
+		VFSItem movedItem = subPublic.resolve("test.txt");
+		Assert.assertNotNull(movedItem);
+		Assert.assertTrue(movedItem instanceof VFSLeaf);
+		Assert.assertTrue(movedItem.exists());
+
+		VFSItem sourceItem = vfsPublic.resolve("test.txt");
+		Assert.assertNull(sourceItem);
+	
+		IOUtils.closeQuietly(conn);
+	}
+	
+	@Test
+	public void testCopy_public()
+	throws IOException, URISyntaxException {
+		//create a user
+		Identity user = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-2b-" + UUID.randomUUID().toString());
+
+		//create a file
+		String publicPath = FolderConfig.getUserHomes() + "/" + user.getName() + "/public";
+		VFSContainer vfsPublic = new OlatRootFolderImpl(publicPath, null);
+		createFile(vfsPublic, "test.txt");
+		VFSContainer subPublic = vfsPublic.createChildContainer("copyto");
+
+		WebDAVConnection conn = new WebDAVConnection();
+		conn.setCredentials(user.getName(), "A6B7C8");
+
+		//author check course folder
+		URI publicUri = conn.getBaseURI().path("webdav").path("home").path("public").build();
+		URI fileUri = UriBuilder.fromUri(publicUri).path("test.txt").build();
+		String destination = UriBuilder.fromUri(publicUri).path("copyto").path("copy.txt").build().toString();
+		int returnMove = conn.copy(fileUri, destination);
+		Assert.assertEquals(201, returnMove);
+
+		//check move
+		VFSItem movedItem = subPublic.resolve("copy.txt");
+		Assert.assertNotNull(movedItem);
+		Assert.assertTrue(movedItem instanceof VFSLeaf);
+		Assert.assertTrue(movedItem.exists());
+
+		VFSItem sourceItem = vfsPublic.resolve("test.txt");
+		Assert.assertNotNull(sourceItem);
+		Assert.assertTrue(sourceItem instanceof VFSLeaf);
+		Assert.assertTrue(sourceItem.exists());
+	
+		IOUtils.closeQuietly(conn);
+	}
+	
 	@Test
 	public void testPut_course()
 	throws IOException, URISyntaxException {
@@ -166,7 +278,9 @@ public class WebDAVCommandsTest extends WebDAVTestCase {
 	}
 	
 	/**
-	 * PROPPATCH is essential for Windows
+	 * PROPPATCH is essential for Windows, the content of the response
+	 * is not important but it must not return an error.
+	 * 
 	 * @throws IOException
 	 * @throws URISyntaxException
 	 */
@@ -192,6 +306,7 @@ public class WebDAVCommandsTest extends WebDAVTestCase {
 		put.setEntity(entity);
 		HttpResponse putResponse = conn.execute(put);
 		Assert.assertEquals(201, putResponse.getStatusLine().getStatusCode());
+		EntityUtils.consume(putResponse.getEntity());
 		
 		//PROPPATCH
 		URI patchUri = UriBuilder.fromUri(privateUri).path("test.txt").build();
@@ -222,12 +337,19 @@ public class WebDAVCommandsTest extends WebDAVTestCase {
 		IOUtils.closeQuietly(conn);
 	}
 	
+	/**
+	 * In the this test, an author and its assistant try to concurrently
+	 * lock a file.
+	 * 
+	 * @throws IOException
+	 * @throws URISyntaxException
+	 */
 	@Test
 	public void testLock()
 	throws IOException, URISyntaxException {
 		//create a user
-		Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-3-" + UUID.randomUUID().toString());
-		Identity assistant = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-4-" + UUID.randomUUID().toString());
+		Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-4-" + UUID.randomUUID().toString());
+		Identity assistant = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-5-" + UUID.randomUUID().toString());
 		deployTestCourse(author, assistant);
 
 		WebDAVConnection authorConn = new WebDAVConnection();
@@ -245,14 +367,89 @@ public class WebDAVCommandsTest extends WebDAVTestCase {
 		String assistantPublicXml = assistantConn.propfind(courseUri, 2);
 		Assert.assertTrue(assistantPublicXml.indexOf("<D:href>/webdav/coursefolders/Kurs/_courseelementdata/</D:href>") > 0);
 
-		//author lock the course folder
+		//PUT a file to lock
+		URI putUri = UriBuilder.fromUri(courseUri).path("Kurs").path("test.txt").build();
+		HttpPut put = authorConn.createPut(putUri);
+		InputStream dataStream = WebDAVCommandsTest.class.getResourceAsStream("text.txt");
+		InputStreamEntity entity = new InputStreamEntity(dataStream, -1);
+		put.setEntity(entity);
+		HttpResponse putResponse = authorConn.execute(put);
+		Assert.assertEquals(201, putResponse.getStatusLine().getStatusCode());
+		EntityUtils.consume(putResponse.getEntity());
+
+		//author lock the file in the course folder
+		String authorLockToken = UUID.randomUUID().toString().replace("-", "").toLowerCase();
+		String authorResponseLockToken = authorConn.lock(putUri, authorLockToken);
+		Assert.assertNotNull(authorResponseLockToken);
 		
+		//coauthor try to lock the same file
+		String coauthorLockToken = UUID.randomUUID().toString().replace("-", "").toLowerCase();
+		int coauthorLock = assistantConn.lockTry(putUri, coauthorLockToken);
+		Assert.assertEquals(423, coauthorLock);// it's lock
 		
+		//author unlock the file
+		int unlockCode = authorConn.unlock(putUri, authorResponseLockToken);
+		Assert.assertEquals(204, unlockCode);
+		
+		//coauthor try a second time to lock the file
+		String coauthorLockToken_2 = UUID.randomUUID().toString().replace("-", "").toLowerCase();
+		int coauthorLock_2 = assistantConn.lockTry(putUri, coauthorLockToken_2);
+		Assert.assertEquals(200, coauthorLock_2);// it's lock
 		
 		IOUtils.closeQuietly(authorConn);
 		IOUtils.closeQuietly(assistantConn);
 	}
 	
+	@Test
+	public void testDelete()
+	throws IOException, URISyntaxException {
+		//create a user
+		Identity user = JunitTestHelper.createAndPersistIdentityAsUser("webdav-6-" + UUID.randomUUID().toString());
+		
+		//create a file
+		String publicPath = FolderConfig.getUserHomes() + "/" + user.getName() + "/public";
+		VFSContainer vfsPublic = new OlatRootFolderImpl(publicPath, null);
+		createFile(vfsPublic, "testDelete.txt");
+		
+		//check
+		VFSItem item = vfsPublic.resolve("testDelete.txt");
+		Assert.assertTrue(item instanceof VFSLeaf);
+		Assert.assertTrue(item.exists());
+		Assert.assertTrue(((VFSLeaf)item).getSize() > 0);
+
+		//delete the file
+		WebDAVConnection conn = new WebDAVConnection();
+		conn.setCredentials(user.getName(), "A6B7C8");
+	
+		//check public folder
+		URI checkUri = conn.getBaseURI().path("webdav").path("home").path("public").path("testDelete.txt").build();
+		String publicXml = conn.propfind(checkUri, 1);
+		Assert.assertTrue(publicXml.indexOf("<D:multistatus") > 0);//Windows need the D namespace
+		Assert.assertTrue(publicXml.indexOf("<D:href>/webdav/home/public/testDelete.txt</D:href>") > 0);//check the root
+
+		//delete the file
+		HttpDelete delete = conn.createDelete(checkUri);
+		HttpResponse deleteResponse = conn.execute(delete);
+		Assert.assertEquals(204, deleteResponse.getStatusLine().getStatusCode());
+		EntityUtils.consume(deleteResponse.getEntity());
+		
+		//check if really deleted
+		VFSItem reloadTestLeaf = vfsPublic.resolve("testDelete.txt");
+		Assert.assertNull(reloadTestLeaf);
+
+		IOUtils.closeQuietly(conn);
+	}
+	
+	private void createFile(VFSContainer container, String filename) throws IOException {
+		VFSLeaf testLeaf = container.createChildLeaf(filename);
+		InputStream in = WebDAVCommandsTest.class.getResourceAsStream("text.txt");
+		OutputStream out = testLeaf.getOutputStream(false);
+		FileUtils.copy(in, out);
+		out.flush();
+		IOUtils.closeQuietly(in);
+		IOUtils.closeQuietly(out);
+	}
+	
 	private void deployTestCourse(Identity author, Identity coAuthor) throws URISyntaxException {
 		URL courseWithForumsUrl = CoursePublishTest.class.getResource("myCourseWS.zip");
 		Assert.assertNotNull(courseWithForumsUrl);
diff --git a/src/test/java/org/olat/core/commons/services/webdav/WebDAVConnection.java b/src/test/java/org/olat/core/commons/services/webdav/WebDAVConnection.java
index 5375091de13fe05451ad0852cd64c92bb834c802..848554fc066ad539167accd4c9456caaf1322bb9 100644
--- a/src/test/java/org/olat/core/commons/services/webdav/WebDAVConnection.java
+++ b/src/test/java/org/olat/core/commons/services/webdav/WebDAVConnection.java
@@ -21,6 +21,7 @@ package org.olat.core.commons.services.webdav;
 
 import java.io.Closeable;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URISyntaxException;
 
@@ -29,15 +30,18 @@ import javax.ws.rs.core.UriBuilder;
 import junit.framework.Assert;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.http.Header;
 import org.apache.http.HttpResponse;
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.UsernamePasswordCredentials;
 import org.apache.http.client.CookieStore;
 import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.methods.HttpDelete;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpOptions;
 import org.apache.http.client.methods.HttpPut;
 import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.BasicCookieStore;
 import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.CloseableHttpClient;
@@ -97,6 +101,75 @@ public class WebDAVConnection implements Closeable {
 		return EntityUtils.toString(response.getEntity());
 	}
 	
+	public int mkcol(URI uri) throws IOException, URISyntaxException {
+		HttpMkcol mkcol = new HttpMkcol(uri);
+		HttpResponse response = execute(mkcol);
+		int returnCode = response.getStatusLine().getStatusCode();
+		EntityUtils.consume(response.getEntity());
+		return returnCode;
+	}
+	
+	public int move(URI uri, String destination) throws IOException, URISyntaxException {
+		HttpMove move = new HttpMove(uri);
+		move.setHeader("Destination", destination);
+		HttpResponse response = execute(move);
+		int returnCode = response.getStatusLine().getStatusCode();
+		EntityUtils.consume(response.getEntity());
+		return returnCode;
+	}
+	
+	public int copy(URI uri, String destination) throws IOException, URISyntaxException {
+		HttpCopy copy = new HttpCopy(uri);
+		copy.setHeader("Destination", destination);
+		HttpResponse response = execute(copy);
+		int returnCode = response.getStatusLine().getStatusCode();
+		EntityUtils.consume(response.getEntity());
+		return returnCode;
+	}
+	
+	public String lock(URI uri, String lockToken) throws IOException, URISyntaxException {
+		HttpLock lock = new HttpLock(uri);
+		decorateLockRequest(lock, lockToken);
+		HttpResponse response = execute(lock);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		Header responseToken = response.getFirstHeader("Lock-Token");
+		Assert.assertNotNull(responseToken);
+		EntityUtils.consume(response.getEntity());
+		return responseToken.getValue();
+	}
+	
+	public int lockTry(URI uri, String lockToken) throws IOException, URISyntaxException {
+		HttpLock lock = new HttpLock(uri);
+		decorateLockRequest(lock, lockToken);
+		HttpResponse response = execute(lock);
+		int returnCode = response.getStatusLine().getStatusCode();
+		EntityUtils.consume(response.getEntity());
+		return returnCode;
+	}
+	
+	private void decorateLockRequest(HttpLock lock, String lockToken) throws UnsupportedEncodingException {
+		lock.addHeader("Lock-Token", lockToken);
+		StringBuilder sb = new StringBuilder();
+		sb.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>")
+		  .append("<D:lockinfo xmlns:D='DAV:'>")
+		  .append("  <D:lockscope><D:exclusive/></D:lockscope>")
+		  .append("  <D:locktype><D:write/></D:locktype>")
+		  .append("  <D:owner>")
+		  .append("       <D:href>").append(lock.getURI().toString()).append("</D:href>")
+		  .append("  </D:owner>")
+		  .append(" </D:lockinfo>");
+		lock.setEntity(new StringEntity(sb.toString()));
+	}
+	
+	public int unlock(URI uri, String lockToken) throws IOException, URISyntaxException {
+		HttpUnlock unlock = new HttpUnlock(uri);
+		unlock.addHeader("Lock-Token", lockToken);
+		HttpResponse response = execute(unlock);
+		int returnCode = response.getStatusLine().getStatusCode();
+		EntityUtils.consume(response.getEntity());
+		return returnCode;
+	}
+	
 	public HttpOptions createOptions(URI uri) throws IOException, URISyntaxException {
 		HttpOptions options = new HttpOptions(uri);
 		return options;	
@@ -108,6 +181,11 @@ public class WebDAVConnection implements Closeable {
 		return put;
 	}
 	
+	public HttpDelete createDelete(URI uri) {
+		HttpDelete delete = new HttpDelete(uri);
+		return delete;
+	}
+	
 	public HttpPropPatch createPropPatch(URI uri) {
 		HttpPropPatch proppatch = new HttpPropPatch(uri);
 		proppatch.addHeader("Accept", "*/*");
diff --git a/src/test/java/org/olat/core/commons/services/webdav/WebDAVTestCase.java b/src/test/java/org/olat/core/commons/services/webdav/WebDAVTestCase.java
index a92b8025362d0a22cb85af79ef7788de3be1eb99..7b77ec4d3eba15e543fcff0085413f2776be5dd4 100644
--- a/src/test/java/org/olat/core/commons/services/webdav/WebDAVTestCase.java
+++ b/src/test/java/org/olat/core/commons/services/webdav/WebDAVTestCase.java
@@ -26,9 +26,14 @@
 
 package org.olat.core.commons.services.webdav;
 
-import java.io.IOException;
+import static io.undertow.servlet.Servlets.defaultContainer;
+import static io.undertow.servlet.Servlets.deployment;
+import static io.undertow.servlet.Servlets.servlet;
+import io.undertow.Undertow;
+import io.undertow.servlet.api.DeploymentInfo;
+import io.undertow.servlet.api.DeploymentManager;
 
-import javax.servlet.Servlet;
+import javax.servlet.ServletException;
 
 import org.junit.BeforeClass;
 import org.olat.core.logging.OLog;
@@ -36,9 +41,6 @@ import org.olat.core.logging.Tracing;
 import org.olat.core.servlets.OpenOLATServlet;
 import org.olat.test.OlatTestCase;
 
-import com.sun.grizzly.http.embed.GrizzlyWebServer;
-import com.sun.grizzly.http.servlet.ServletAdapter;
-
 /**
  * 
  * Description:<br>
@@ -55,33 +57,33 @@ public abstract class WebDAVTestCase extends OlatTestCase {
 	public final static String HOST = "localhost";
 	public final static String PROTOCOL = "http";
 
-	private static GrizzlyWebServer webServer;
+	private static Undertow webServer;
 	
 	@BeforeClass
 	public static void setUp() throws Exception {
+
+		
 		try {
 			if(webServer == null) {
-				webServer = new GrizzlyWebServer(PORT);
-				webServer.useAsynchronousWrite(false);
-				ServletAdapter sa = new ServletAdapter();
-				Servlet servletInstance = null;
-				try {
-					servletInstance = new OpenOLATServlet();
-				} catch (Exception ex) {
-					log.error("Cannot instantiate the Grizzly Servlet Container", ex);
-				}
-				sa.setServletInstance(servletInstance);
-				sa.addInitParameter("debug", "0");
-				sa.addInitParameter("input", "32768");
-				sa.addInitParameter("output", "32768");
-				sa.addInitParameter("listings", "true");
-				sa.addInitParameter("readonly", "false");
-				webServer.addGrizzlyAdapter(sa, new String[]{""});
+				DeploymentInfo servletBuilder = deployment()
+	                    .setClassLoader(WebDAVTestCase.class.getClassLoader())
+	                    .setContextPath("/")
+	                    .setDeploymentName("test.war")
+	                    .addServlets(
+	                            servlet("MessageServlet", OpenOLATServlet.class)
+	                                    .addInitParam("message", "Hello World")
+	                                    .addMapping("/*"));
+
+	            DeploymentManager manager = defaultContainer().addDeployment(servletBuilder);
+	            manager.deploy();
 
-				log.info("Starting the Grizzly Web Container for WebDAV...");
-				webServer.start();
+	            webServer = Undertow.builder()
+	                    .addListener(PORT, HOST)
+	                    .setHandler(manager.start())
+	                    .build();
+	            webServer.start();
 			}
-		} catch (IOException ex) {
+		} catch (ServletException ex) {
 			log.error("Cannot start the Grizzly Web Container for WebDAV");
 		}
 	}
diff --git a/src/test/java/org/olat/restapi/RestConnection.java b/src/test/java/org/olat/restapi/RestConnection.java
index 06d90edb5fa8c7c1849aa84e9e3e4934f2911c3b..2e15fb5bce5d7174285838c58887557ca98f92e5 100644
--- a/src/test/java/org/olat/restapi/RestConnection.java
+++ b/src/test/java/org/olat/restapi/RestConnection.java
@@ -70,7 +70,7 @@ import org.olat.restapi.security.RestSecurityHelper;
 /**
  * 
  * Description:<br>
- * Manage a connection to the grizzly server used by the unit test
+ * Manage a connection to the server used by the unit test
  * with some helpers methods.
  * 
  * <P>
diff --git a/src/test/java/org/olat/test/OlatJerseyTestCase.java b/src/test/java/org/olat/test/OlatJerseyTestCase.java
index 9bda28718b01c7219c226be56a075de0fbc2d6df..582f71a2d24a3270ef8e69a128d0f4fb5f99ad00 100644
--- a/src/test/java/org/olat/test/OlatJerseyTestCase.java
+++ b/src/test/java/org/olat/test/OlatJerseyTestCase.java
@@ -26,13 +26,20 @@
 
 package org.olat.test;
 
-import java.io.IOException;
+import static io.undertow.servlet.Servlets.defaultContainer;
+import static io.undertow.servlet.Servlets.deployment;
+import static io.undertow.servlet.Servlets.filter;
+import static io.undertow.servlet.Servlets.servlet;
+import io.undertow.Undertow;
+import io.undertow.servlet.api.DeploymentInfo;
+import io.undertow.servlet.api.DeploymentManager;
+
 import java.io.InputStream;
 import java.net.URI;
 import java.util.List;
 
-import javax.servlet.Servlet;
-import javax.servlet.http.HttpServlet;
+import javax.servlet.DispatcherType;
+import javax.servlet.ServletException;
 import javax.ws.rs.core.UriBuilder;
 
 import org.codehaus.jackson.JsonFactory;
@@ -49,13 +56,10 @@ import org.olat.restapi.support.vo.FileVO;
 import org.olat.restapi.support.vo.LinkVO;
 import org.springframework.beans.factory.annotation.Autowired;
 
-import com.sun.grizzly.http.embed.GrizzlyWebServer;
-import com.sun.grizzly.http.servlet.ServletAdapter;
-
 /**
  * 
  * Description:<br>
- * Abstract class which start and stop a grizzly server for every test
+ * Abstract class which start and stop an undertow server
  * 
  * <P>
  * Initial Date:  14 apr. 2010 <br>
@@ -75,7 +79,7 @@ public abstract class OlatJerseyTestCase extends OlatTestCase {
 	public final static String PROTOCOL = "http";
 
 	private static boolean webServerStarted = false;
-	private static GrizzlyWebServer webServer;
+	private static Undertow webServer;
 	
 	@Autowired
 	private RestModule restModule;
@@ -85,28 +89,38 @@ public abstract class OlatJerseyTestCase extends OlatTestCase {
 	 */
 	public OlatJerseyTestCase() {
 		super();
-		instantiateGrizzlyWebServer();
+		instantiateServer();
 	}
 	
 	/**
-	 * Instantiates the Grizzly Web Server
+	 * Instantiates the server
 	 */
-	private void instantiateGrizzlyWebServer() {
+	private void instantiateServer() {
 		if(webServer == null) {
-			webServer = new GrizzlyWebServer(PORT);
-			webServer.useAsynchronousWrite(false);
-			ServletAdapter sa = new ServletAdapter();
-			Servlet servletInstance = null;
 			try {
-				servletInstance = (HttpServlet)Class.forName("com.sun.jersey.spi.container.servlet.ServletContainer").newInstance();
-			} catch (Exception ex) {
-				log.error("Cannot instantiate the Grizzly Servlet Container", ex);
+				DeploymentInfo servletBuilder = deployment()
+				        .setClassLoader(OlatJerseyTestCase.class.getClassLoader())
+				        .setContextPath("/" + CONTEXT_PATH)
+				        .setDeploymentName("rest.war")
+				        .addServlets(
+				                servlet("REST Servlet",  com.sun.jersey.spi.container.servlet.ServletContainer.class)
+		        		        		.addInitParam("javax.ws.rs.Application", OlatRestApplication.class.getName())
+				                        .addMapping("/*"))
+				        .addFilters(filter("REST security filter", RestApiLoginFilter.class))
+				        .addFilterUrlMapping("REST security filter", "/*", DispatcherType.REQUEST);
+
+				DeploymentManager manager = defaultContainer().addDeployment(servletBuilder);
+				manager.deploy();
+
+				webServer = Undertow.builder()
+				        .addListener(PORT, HOST)
+				        .setHandler(manager.start())
+				        .build();
+				webServer.start();
+				webServerStarted = true;
+			} catch (ServletException e) {
+				log.error("", e);
 			}
-			sa.setServletInstance(servletInstance);
-			sa.addFilter(new RestApiLoginFilter(), "jerseyfilter", null);
-			sa.addInitParameter("javax.ws.rs.Application", OlatRestApplication.class.getName());
-			sa.setContextPath("/" + CONTEXT_PATH);
-			webServer.addGrizzlyAdapter(sa, new String[]{""});
 		}
 	}
 	
@@ -121,17 +135,13 @@ public abstract class OlatJerseyTestCase extends OlatTestCase {
   @Before
   public void setUp() throws Exception {
   	//always enabled the REST API for testing
-		restModule.setEnabled(true);
-  	
-		try {
-			if(!webServerStarted) {
-				log.info("Starting the Grizzly Web Container...");
-				webServer.start();
-				webServerStarted=true;
-			}
-		} catch (IOException ex) {
-			log.error("Cannot start the Grizzly Web Container");
-		}
+	restModule.setEnabled(true);
+
+	if(!webServerStarted) {
+		log.info("Starting the Grizzly Web Container...");
+		webServer.start();
+		webServerStarted=true;
+	}
   }
 	
 	protected List<ErrorVO> parseErrorArray(InputStream body) {
@@ -139,7 +149,7 @@ public abstract class OlatJerseyTestCase extends OlatTestCase {
 			ObjectMapper mapper = new ObjectMapper(jsonFactory); 
 			return mapper.readValue(body, new TypeReference<List<ErrorVO>>(){/* */});
 		} catch (Exception e) {
-			e.printStackTrace();
+			log.error("", e);
 			return null;
 		}
 	}
@@ -149,7 +159,7 @@ public abstract class OlatJerseyTestCase extends OlatTestCase {
 			ObjectMapper mapper = new ObjectMapper(jsonFactory); 
 			return mapper.readValue(body, new TypeReference<List<LinkVO>>(){/* */});
 		} catch (Exception e) {
-			e.printStackTrace();
+			log.error("", e);
 			return null;
 		}
 	}
@@ -159,7 +169,7 @@ public abstract class OlatJerseyTestCase extends OlatTestCase {
 			ObjectMapper mapper = new ObjectMapper(jsonFactory); 
 			return mapper.readValue(body, new TypeReference<List<FileVO>>(){/* */});
 		} catch (Exception e) {
-			e.printStackTrace();
+			log.error("", e);
 			return null;
 		}
 	}