diff --git a/ccm-core/src/main/java/org/libreccm/webdav/xml/WebDavContextResolver.java b/ccm-core/src/main/java/org/libreccm/webdav/xml/WebDavContextResolver.java
new file mode 100644
index 000000000..49c198628
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/webdav/xml/WebDavContextResolver.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2018 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.webdav.xml;
+
+import org.libreccm.core.UnexpectedErrorException;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.ext.ContextResolver;
+import javax.ws.rs.ext.Provider;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.JAXBIntrospector;
+
+/**
+ * Provides support for custom extensions to WebDAV, like custom Properties and
+ * XML Elements.
+ *
+ * WebDAV allows custom extensions for XML Elements and Properties. To enable
+ * JAX-RS to deal with these, each of them must be implemented as a JAXB class
+ * and registered by passing it to the constructor of this resolver.
+ *
+ * The class is based on a class/interface from java.net WebDAV Project:
+ *
+ * https://gitlab.com/headcrashing/webdav-jaxrs/blob/master/src/main/java/net/java/dev/webdav/jaxrs/Headers.java
+ *
+ *
+ * @author Markus KARG (mkarg@java.net)
+ * @author Jens Pelzetter
+ *
+ * @see
+ * Chapter
+ * 17 "XML Extensibility in DAV" of RFC 2616 "Hypertext Transfer Protocol --
+ * HTTP/1.1"
+ */
+@Provider
+@Produces(MediaType.APPLICATION_XML)
+public class WebDavContextResolver implements ContextResolver {
+
+ private final JAXBContext context;
+
+ private final JAXBIntrospector introspector;
+
+ /**
+ * Creates an instance of this resolver, registering the provided custom XML
+ * Elements and Properties.
+ *
+ * @param additionalClasses The custom extensions (JAXB classes) to be
+ * registered (can be left blank).
+ *
+ * @throws JAXBException if an error was encountered while creating the
+ * JAXBContext, such as (but not limited to): No JAXB
+ * implementation was discovered, Classes use JAXB
+ * annotations incorrectly, Classes have colliding
+ * annotations (i.e., two classes with the same type
+ * name), The JAXB implementation was unable to locate
+ * provider-specific out-of-band information (such as
+ * additional files generated at the development
+ * time.)
+ */
+ public WebDavContextResolver(final Class>... additionalClasses)
+ throws JAXBException {
+
+ this.context = WebDavJAXBContextBuilder.build(additionalClasses);
+ this.introspector = this.context.createJAXBIntrospector();
+ }
+
+ /**
+ * @return A single, shared context for both, WebDAV XML Elements and
+ * Properties and custom extensions.
+ */
+ @Override
+ public JAXBContext getContext(final Class> type) {
+
+ if (introspector.isElement(buildInstanceOf(type))) {
+ return context;
+ } else {
+ return null;
+ }
+ }
+
+ private T buildInstanceOf(final Class type) {
+
+ if (type == null) {
+
+ return null;
+
+ } else if (type.isEnum()) {
+
+ final T[] enumConstants = type.getEnumConstants();
+ if (enumConstants.length > 0) {
+ return enumConstants[0];
+ } else {
+ return null;
+ }
+
+ } else {
+
+ try {
+ final Constructor constructor = type
+ .getDeclaredConstructor();
+ constructor.setAccessible(true);
+ return constructor.newInstance();
+ } catch (NoSuchMethodException
+ | InstantiationException
+ | IllegalAccessException
+ | InvocationTargetException ex) {
+
+ throw new UnexpectedErrorException(ex);
+ }
+ }
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/webdav/xml/WebDavJAXBContextBuilder.java b/ccm-core/src/main/java/org/libreccm/webdav/xml/WebDavJAXBContextBuilder.java
new file mode 100644
index 000000000..1f69d5d64
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/webdav/xml/WebDavJAXBContextBuilder.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2018 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.webdav.xml;
+
+import org.libreccm.webdav.conditions.CannotModifyProtectedProperty;
+import org.libreccm.webdav.conditions.LockTokenMatchesRequestUri;
+import org.libreccm.webdav.conditions.LockTokenSubmitted;
+import org.libreccm.webdav.conditions.NoConflictingLock;
+import org.libreccm.webdav.conditions.NoExternalEntities;
+import org.libreccm.webdav.conditions.PreservedLiveProperties;
+import org.libreccm.webdav.conditions.PropFindFiniteDepth;
+import org.libreccm.webdav.xml.elements.ActiveLock;
+import org.libreccm.webdav.xml.elements.AllProp;
+import org.libreccm.webdav.xml.elements.Collection;
+import org.libreccm.webdav.xml.elements.Depth;
+import org.libreccm.webdav.xml.elements.Exclusive;
+import org.libreccm.webdav.xml.elements.HRef;
+import org.libreccm.webdav.xml.elements.Include;
+import org.libreccm.webdav.xml.elements.Location;
+import org.libreccm.webdav.xml.elements.LockEntry;
+import org.libreccm.webdav.xml.elements.LockInfo;
+import org.libreccm.webdav.xml.elements.LockRoot;
+import org.libreccm.webdav.xml.elements.LockScope;
+import org.libreccm.webdav.xml.elements.LockToken;
+import org.libreccm.webdav.xml.elements.LockType;
+import org.libreccm.webdav.xml.elements.MultiStatus;
+import org.libreccm.webdav.xml.elements.Owner;
+import org.libreccm.webdav.xml.elements.Prop;
+import org.libreccm.webdav.xml.elements.PropFind;
+import org.libreccm.webdav.xml.elements.PropName;
+import org.libreccm.webdav.xml.elements.PropStat;
+import org.libreccm.webdav.xml.elements.PropertyUpdate;
+import org.libreccm.webdav.xml.elements.Remove;
+import org.libreccm.webdav.xml.elements.ResponseDescription;
+import org.libreccm.webdav.xml.elements.Shared;
+import org.libreccm.webdav.xml.elements.Status;
+import org.libreccm.webdav.xml.elements.TimeOut;
+import org.libreccm.webdav.xml.elements.Write;
+import org.libreccm.webdav.xml.properties.CreationDate;
+import org.libreccm.webdav.xml.properties.DisplayName;
+import org.libreccm.webdav.xml.properties.GetContentLanguage;
+import org.libreccm.webdav.xml.properties.GetContentLength;
+import org.libreccm.webdav.xml.properties.GetContentType;
+import org.libreccm.webdav.xml.properties.GetETag;
+import org.libreccm.webdav.xml.properties.GetLastModified;
+import org.libreccm.webdav.xml.properties.LockDiscovery;
+import org.libreccm.webdav.xml.properties.ResourceType;
+import org.libreccm.webdav.xml.properties.SupportedLock;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.text.Utilities;
+import javax.ws.rs.core.Response;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+
+/**
+ * Provides support for custom extensions to WebDAV, like custom Properties and
+ * XML Elements.
+ *
+ * WebDAV allows custom extensions for XML Elements and Properties. To enable
+ * JAX-RS to deal with these, each of them must be implemented as a JAXB class
+ * and registered by passing it to the constructor of this factory.
+ *
+ * The class is based on a class/interface from java.net WebDAV Project:
+ *
+ * https://gitlab.com/headcrashing/webdav-jaxrs/blob/master/src/main/java/net/java/dev/webdav/jaxrs/Headers.java
+ *
+ * @author Markus KARG (mkarg@java.net)
+ * @author Jens Pelzetter
+ *
+ * @see
+ * Chapter
+ * 17 "XML Extensibility in DAV" of RFC 2616 "Hypertext Transfer Protocol --
+ * HTTP/1.1"
+ */
+final class WebDavJAXBContextBuilder {
+
+ /**
+ * Builds a JAXB context for WebDAV.
+ *
+ * @param auxiliaryClasses Optional set of custom XML elements which shall
+ * get part of the context.
+ *
+ * @throws JAXBException If JAXB cannot create the context.
+ */
+ public static final JAXBContext build(final Class>... auxiliaryClasses)
+ throws JAXBException {
+
+ final Class>[] webDavClasses = new Class>[]{
+ ActiveLock.class,
+ AllProp.class,
+ CannotModifyProtectedProperty.class,
+ Collection.class,
+ CreationDate.class,
+ Depth.class,
+ DisplayName.class,
+ Error.class,
+ Exclusive.class,
+ GetContentLanguage.class,
+ GetContentLength.class,
+ GetContentType.class,
+ GetETag.class,
+ GetLastModified.class,
+ HRef.class,
+ Include.class,
+ Location.class,
+ LockDiscovery.class,
+ LockEntry.class,
+ LockInfo.class,
+ LockRoot.class,
+ LockScope.class,
+ LockToken.class,
+ LockTokenMatchesRequestUri.class,
+ LockTokenSubmitted.class,
+ LockType.class,
+ MultiStatus.class,
+ NoConflictingLock.class,
+ NoExternalEntities.class,
+ Owner.class,
+ PreservedLiveProperties.class,
+ Prop.class,
+ PropertyUpdate.class,
+ PropFind.class,
+ PropFindFiniteDepth.class,
+ PropName.class,
+ PropStat.class,
+ Remove.class,
+ ResourceType.class,
+ Response.class,
+ ResponseDescription.class,
+ Set.class, Shared.class,
+ Status.class,
+ SupportedLock.class,
+ TimeOut.class,
+ Write.class};
+
+ final List> allClasses = new ArrayList<>();
+ allClasses.addAll(Arrays.asList(webDavClasses));
+ allClasses.addAll(Arrays.asList(auxiliaryClasses));
+
+
+ return JAXBContext.newInstance(allClasses.toArray(new Class>[]{}));
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/CreationDate.java b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/CreationDate.java
similarity index 98%
rename from ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/CreationDate.java
rename to ccm-core/src/main/java/org/libreccm/webdav/xml/properties/CreationDate.java
index e1c99e163..679029b41 100644
--- a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/CreationDate.java
+++ b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/CreationDate.java
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.webdav.xml.elements.properties;
+package org.libreccm.webdav.xml.properties;
import org.libreccm.webdav.ConstantsAdapter;
import org.libreccm.webdav.xml.elements.Rfc3339DateTimeFormat;
diff --git a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/DisplayName.java b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/DisplayName.java
similarity index 98%
rename from ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/DisplayName.java
rename to ccm-core/src/main/java/org/libreccm/webdav/xml/properties/DisplayName.java
index a796d3d36..659dabe28 100644
--- a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/DisplayName.java
+++ b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/DisplayName.java
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.webdav.xml.elements.properties;
+package org.libreccm.webdav.xml.properties;
import org.libreccm.webdav.ConstantsAdapter;
diff --git a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetContentLanguage.java b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetContentLanguage.java
similarity index 98%
rename from ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetContentLanguage.java
rename to ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetContentLanguage.java
index 095739145..2dc1f5794 100644
--- a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetContentLanguage.java
+++ b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetContentLanguage.java
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.webdav.xml.elements.properties;
+package org.libreccm.webdav.xml.properties;
import org.libreccm.webdav.ConstantsAdapter;
diff --git a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetContentLength.java b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetContentLength.java
similarity index 98%
rename from ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetContentLength.java
rename to ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetContentLength.java
index f7242d473..a997977cc 100644
--- a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetContentLength.java
+++ b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetContentLength.java
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.webdav.xml.elements.properties;
+package org.libreccm.webdav.xml.properties;
import org.libreccm.webdav.ConstantsAdapter;
diff --git a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetContentType.java b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetContentType.java
similarity index 98%
rename from ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetContentType.java
rename to ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetContentType.java
index c4172930e..589b227e6 100644
--- a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetContentType.java
+++ b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetContentType.java
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.webdav.xml.elements.properties;
+package org.libreccm.webdav.xml.properties;
import org.libreccm.webdav.ConstantsAdapter;
diff --git a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetETag.java b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetETag.java
similarity index 98%
rename from ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetETag.java
rename to ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetETag.java
index dc120249b..913727ca0 100644
--- a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetETag.java
+++ b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetETag.java
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.webdav.xml.elements.properties;
+package org.libreccm.webdav.xml.properties;
import org.libreccm.webdav.ConstantsAdapter;
diff --git a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetLastModified.java b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetLastModified.java
similarity index 98%
rename from ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetLastModified.java
rename to ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetLastModified.java
index f846f5768..d96414b29 100644
--- a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/GetLastModified.java
+++ b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/GetLastModified.java
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.webdav.xml.elements.properties;
+package org.libreccm.webdav.xml.properties;
import org.libreccm.webdav.ConstantsAdapter;
import org.libreccm.webdav.xml.elements.Rfc1123DateFormat;
diff --git a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/LockDiscovery.java b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/LockDiscovery.java
similarity index 98%
rename from ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/LockDiscovery.java
rename to ccm-core/src/main/java/org/libreccm/webdav/xml/properties/LockDiscovery.java
index 9c03a6551..8eead9a00 100644
--- a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/LockDiscovery.java
+++ b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/LockDiscovery.java
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.webdav.xml.elements.properties;
+package org.libreccm.webdav.xml.properties;
import org.libreccm.webdav.ConstantsAdapter;
import org.libreccm.webdav.xml.elements.ActiveLock;
diff --git a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/ResourceType.java b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/ResourceType.java
similarity index 98%
rename from ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/ResourceType.java
rename to ccm-core/src/main/java/org/libreccm/webdav/xml/properties/ResourceType.java
index 57ec6e513..f8befb065 100644
--- a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/ResourceType.java
+++ b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/ResourceType.java
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.webdav.xml.elements.properties;
+package org.libreccm.webdav.xml.properties;
import org.libreccm.webdav.ConstantsAdapter;
import org.libreccm.webdav.xml.elements.Collection;
diff --git a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/SupportedLock.java b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/SupportedLock.java
similarity index 98%
rename from ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/SupportedLock.java
rename to ccm-core/src/main/java/org/libreccm/webdav/xml/properties/SupportedLock.java
index 841c5871b..34105e0e7 100644
--- a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/SupportedLock.java
+++ b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/SupportedLock.java
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.webdav.xml.elements.properties;
+package org.libreccm.webdav.xml.properties;
import org.libreccm.webdav.ConstantsAdapter;
import org.libreccm.webdav.xml.elements.LockEntry;
diff --git a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/package-info.java b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/package-info.java
similarity index 97%
rename from ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/package-info.java
rename to ccm-core/src/main/java/org/libreccm/webdav/xml/properties/package-info.java
index 4a70d6a29..f12f2e795 100644
--- a/ccm-core/src/main/java/org/libreccm/webdav/xml/elements/properties/package-info.java
+++ b/ccm-core/src/main/java/org/libreccm/webdav/xml/properties/package-info.java
@@ -35,7 +35,7 @@
@XmlSchema(namespace = "DAV:",
xmlns = @XmlNs(prefix = "D", namespaceURI = "DAV:"),
elementFormDefault = QUALIFIED)
-package org.libreccm.webdav.xml.elements.properties;
+package org.libreccm.webdav.xml.properties;
import static javax.xml.bind.annotation.XmlNsForm.QUALIFIED;