Adding metadatareader interface
diff --git a/archiva-modules/archiva-base/archiva-configuration/pom.xml b/archiva-modules/archiva-base/archiva-configuration/pom.xml
index ec79c43..1275ca1 100644
--- a/archiva-modules/archiva-base/archiva-configuration/pom.xml
+++ b/archiva-modules/archiva-base/archiva-configuration/pom.xml
@@ -96,13 +96,7 @@
         </exclusion>
       </exclusions>
     </dependency>
-    <!--
-    <dependency>
-      <groupId>commons-collections</groupId>
-      <artifactId>commons-collections</artifactId>
-      <version>3.2.2</version>
-    </dependency>
-    -->
+
     <dependency>
       <groupId>commons-io</groupId>
       <artifactId>commons-io</artifactId>
@@ -115,17 +109,10 @@
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-collections4</artifactId>
     </dependency>
-    <!--
-    <dependency>
-      <groupId>commons-beanutils</groupId>
-      <artifactId>commons-beanutils</artifactId>
-    </dependency>
-  -->
 
 
     <!-- Test scope -->
 
-
     <dependency>
       <groupId>org.easymock</groupId>
       <artifactId>easymock</artifactId>
diff --git a/archiva-modules/archiva-base/archiva-repository-api/pom.xml b/archiva-modules/archiva-base/archiva-repository-api/pom.xml
index 1c7675b..584375e 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/pom.xml
+++ b/archiva-modules/archiva-base/archiva-repository-api/pom.xml
@@ -64,6 +64,10 @@
       <artifactId>javax.inject</artifactId>
     </dependency>
     <dependency>
+      <groupId>javax.annotation</groupId>
+      <artifactId>javax.annotation-api</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.apache.archiva.components.registry</groupId>
       <artifactId>archiva-components-spring-registry-api</artifactId>
     </dependency>
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryRegistry.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryRegistry.java
index fec96f6..bb6bbc9 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryRegistry.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryRegistry.java
@@ -27,6 +27,8 @@
 import org.apache.archiva.event.EventSource;
 import org.apache.archiva.indexer.ArchivaIndexManager;
 import org.apache.archiva.indexer.IndexUpdateFailedException;
+import org.apache.archiva.repository.metadata.MetadataReader;
+import org.apache.archiva.repository.storage.StorageAsset;
 
 import java.util.Collection;
 
@@ -41,12 +43,36 @@
  */
 public interface RepositoryRegistry extends EventSource
 {
+    /**
+     * Set the configuration for the registry
+     * @param archivaConfiguration
+     */
     void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration );
 
+    /**
+     * Return the index manager for the given repository type
+     * @param type the repository type
+     * @return the index manager, if it exists
+     */
     ArchivaIndexManager getIndexManager( RepositoryType type );
 
+    /**
+     * Returns the metadatareader for the given repository type
+     * @param type the repository type
+     * @return the metadata reader instance
+     */
+    MetadataReader getMetadataReader(RepositoryType type) throws UnsupportedRepositoryTypeException;
+
+    /**
+     * Returns all registered repositories
+     * @return the list of repositories
+     */
     Collection<Repository> getRepositories( );
 
+    /**
+     * Returns all managed repositories
+     * @return the list of managed repositories
+     */
     Collection<ManagedRepository> getManagedRepositories( );
 
     Collection<RemoteRepository> getRemoteRepositories( );
@@ -106,4 +132,11 @@
     <T extends Repository> Repository clone( T repo, String newId ) throws RepositoryException;
 
     RemoteRepository clone( RemoteRepository repo, String newId ) throws RepositoryException;
+
+    /**
+     * Return the repository that stores the given asset.
+     * @param asset the asset
+     * @return the repository or <code>null</code> if no matching repository is found
+     */
+    Repository getRepositoryOfAsset( StorageAsset asset );
 }
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/metadata/MetadataReader.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/metadata/MetadataReader.java
new file mode 100644
index 0000000..74bacb7
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/metadata/MetadataReader.java
@@ -0,0 +1,55 @@
+package org.apache.archiva.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.archiva.model.ArchivaRepositoryMetadata;
+import org.apache.archiva.repository.RepositoryType;
+import org.apache.archiva.repository.storage.StorageAsset;
+
+/**
+ * Interface for reading metadata from a given file
+ */
+public interface MetadataReader
+{
+    /**
+     * Reads the given metadata file and returns the corresponding metadata object.
+     * @param asset The asset where the metadata should be read from
+     * @return The parsed metadata
+     * @throws RepositoryMetadataException if the metadata could not be read
+     */
+    ArchivaRepositoryMetadata read( StorageAsset asset ) throws RepositoryMetadataException;
+
+    /**
+     * Returns <code>true</code>, if the given path is a valid path for a metadata file, otherwise <code>false</code>
+     * The implementation should not access the file directly, just use the path for validation.
+     * @param path the path to the metadata file / asset
+     * @return <code>true</code>, if the path is valid for a metadata file otherwise <code>false</code>
+     */
+    boolean isValidMetadataPath(String path);
+
+    /**
+     * Returns <code>true</code>, if this metadata reader instance can be used to read metadata for the
+     * given repository type, otherwise <code>false</code>.
+     *
+     * @param repositoryType the repository type to check for
+     * @return <code>true</code>, if this is a implementation for the given type, otherwise <code>false</code>
+     */
+    boolean isValidForType(RepositoryType repositoryType);
+}
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/pom.xml b/archiva-modules/archiva-base/archiva-repository-layer/pom.xml
index bc03101..a5f22a3 100644
--- a/archiva-modules/archiva-base/archiva-repository-layer/pom.xml
+++ b/archiva-modules/archiva-base/archiva-repository-layer/pom.xml
@@ -83,10 +83,16 @@
       <version>${project.version}</version>
       <scope>test</scope>
     </dependency>
+    <!--
     <dependency>
       <groupId>org.apache.archiva</groupId>
       <artifactId>metadata-model</artifactId>
     </dependency>
+    -->
+    <dependency>
+      <groupId>org.apache.archiva.components.registry</groupId>
+      <artifactId>archiva-components-spring-registry-api</artifactId>
+    </dependency>
     <dependency>
       <groupId>com.cronutils</groupId>
       <artifactId>cron-utils</artifactId>
@@ -97,6 +103,10 @@
       <scope>provided</scope>
     </dependency>
     <dependency>
+      <groupId>javax.annotation</groupId>
+      <artifactId>javax.annotation-api</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-lang3</artifactId>
     </dependency>
@@ -111,21 +121,25 @@
 
 
     <!-- Test scope -->
+    <!--
     <dependency>
       <groupId>commons-beanutils</groupId>
       <artifactId>commons-beanutils</artifactId>
       <scope>test</scope>
     </dependency>
+    -->
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-slf4j-impl</artifactId>
       <scope>test</scope>
     </dependency>
+    <!--
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-1.2-api</artifactId>
       <scope>test</scope>
     </dependency>
+    -->
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-core</artifactId>
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/ArchivaRepositoryRegistry.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/ArchivaRepositoryRegistry.java
index 0f0d4bf..1c10a2a 100644
--- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/ArchivaRepositoryRegistry.java
+++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/ArchivaRepositoryRegistry.java
@@ -38,10 +38,13 @@
 import org.apache.archiva.repository.RepositoryProvider;
 import org.apache.archiva.repository.RepositoryRegistry;
 import org.apache.archiva.repository.RepositoryType;
+import org.apache.archiva.repository.UnsupportedRepositoryTypeException;
 import org.apache.archiva.repository.event.*;
 import org.apache.archiva.event.EventHandler;
 import org.apache.archiva.repository.features.IndexCreationFeature;
 import org.apache.archiva.repository.features.StagingRepositoryFeature;
+import org.apache.archiva.repository.metadata.MetadataReader;
+import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -89,6 +92,9 @@
     ArchivaConfiguration archivaConfiguration;
 
     @Inject
+    List<MetadataReader> metadataReaderList;
+
+    @Inject
     @Named("repositoryContentFactory#default")
     RepositoryContentFactory repositoryContentFactory;
 
@@ -254,6 +260,16 @@
         return indexManagerFactory.getIndexManager(type);
     }
 
+    @Override
+    public MetadataReader getMetadataReader( final RepositoryType type ) throws UnsupportedRepositoryTypeException
+    {
+        if (metadataReaderList!=null) {
+            return metadataReaderList.stream( ).filter( mr -> mr.isValidForType( type ) ).findFirst( ).orElseThrow( ( ) -> new UnsupportedRepositoryTypeException( type ) );
+        } else {
+            throw new UnsupportedRepositoryTypeException( type );
+        }
+    }
+
     private void createIndexingContext( EditableRepository editableRepo) throws RepositoryException {
         if (editableRepo.supportsFeature(IndexCreationFeature.class)) {
             ArchivaIndexManager idxManager = getIndexManager(editableRepo.getType());
@@ -1261,6 +1277,13 @@
         return cloned;
     }
 
+    @Override
+    public Repository getRepositoryOfAsset( StorageAsset asset )
+    {
+        return getManagedRepositories( ).stream( ).filter( r -> r.getAsset( "" )
+            .getStorage( ).equals( asset.getStorage( ) ) ).findFirst( ).orElse( null );
+    }
+
 
     @Override
     public void configurationEvent(ConfigurationEvent event) {
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/metadata/base/MetadataTools.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/metadata/base/MetadataTools.java
index 53786b1..d85b3a3 100644
--- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/metadata/base/MetadataTools.java
+++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/metadata/base/MetadataTools.java
@@ -30,7 +30,7 @@
 import org.apache.archiva.configuration.ConfigurationNames;
 import org.apache.archiva.configuration.FileTypes;
 import org.apache.archiva.configuration.ProxyConnectorConfiguration;
-import org.apache.archiva.maven2.metadata.MavenMetadataReader;
+// import org.apache.archiva.maven2.metadata.MavenMetadataReader;
 import org.apache.archiva.model.ArchivaRepositoryMetadata;
 import org.apache.archiva.model.ArtifactReference;
 import org.apache.archiva.model.Plugin;
@@ -43,6 +43,10 @@
 import org.apache.archiva.repository.LayoutException;
 import org.apache.archiva.repository.ManagedRepositoryContent;
 import org.apache.archiva.repository.RemoteRepositoryContent;
+import org.apache.archiva.repository.Repository;
+import org.apache.archiva.repository.RepositoryRegistry;
+import org.apache.archiva.repository.RepositoryType;
+import org.apache.archiva.repository.metadata.MetadataReader;
 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.archiva.xml.XMLException;
@@ -75,7 +79,7 @@
 public class MetadataTools
     implements RegistryListener, ConfigurationListener
 {
-    private Logger log = LoggerFactory.getLogger( getClass() );
+    private static final Logger log = LoggerFactory.getLogger( MetadataTools.class );
 
     public static final String MAVEN_METADATA = "maven-metadata.xml";
 
@@ -85,6 +89,9 @@
 
     private static final char GROUP_SEPARATOR = '.';
 
+    @Inject
+    private RepositoryRegistry repositoryRegistry;
+
     /**
      *
      */
@@ -359,26 +366,12 @@
     public ArchivaRepositoryMetadata readProxyMetadata( ManagedRepositoryContent managedRepository,
                                                         ProjectReference reference, String proxyId )
     {
+        MetadataReader reader = getMetadataReader( managedRepository );
+
         String metadataPath = getRepositorySpecificName( proxyId, toPath( reference ) );
         StorageAsset metadataFile = managedRepository.getRepository().getAsset( metadataPath );
 
-        if ( !metadataFile.exists() || metadataFile.isContainer())
-        {
-            // Nothing to do. return null.
-            return null;
-        }
-
-        try
-        {
-            return MavenMetadataReader.read( metadataFile );
-        }
-        catch (XMLException | IOException e )
-        {
-            // TODO: [monitor] consider a monitor for this event.
-            // TODO: consider a read-redo on monitor return code?
-            log.warn( "Unable to read metadata: {}", metadataFile.getPath(), e );
-            return null;
-        }
+        return readMetadataFile( managedRepository, metadataFile );
     }
 
     public ArchivaRepositoryMetadata readProxyMetadata( ManagedRepositoryContent managedRepository,
@@ -386,24 +379,7 @@
     {
         String metadataPath = getRepositorySpecificName( proxyId, logicalResource );
         StorageAsset metadataFile = managedRepository.getRepository().getAsset( metadataPath );
-
-        if ( !metadataFile.exists() || metadataFile.isContainer())
-        {
-            // Nothing to do. return null.
-            return null;
-        }
-
-        try
-        {
-            return MavenMetadataReader.read( metadataFile );
-        }
-        catch (XMLException | IOException e )
-        {
-            // TODO: [monitor] consider a monitor for this event.
-            // TODO: consider a read-redo on monitor return code?
-            log.warn( "Unable to read metadata: {}", metadataFile.getPath(), e );
-            return null;
-        }
+        return readMetadataFile( managedRepository, metadataFile );
     }
 
     public ArchivaRepositoryMetadata readProxyMetadata( ManagedRepositoryContent managedRepository,
@@ -411,24 +387,7 @@
     {
         String metadataPath = getRepositorySpecificName( proxyId, toPath( reference ) );
         StorageAsset metadataFile = managedRepository.getRepository().getAsset( metadataPath );
-
-        if ( !metadataFile.exists() || metadataFile.isContainer())
-        {
-            // Nothing to do. return null.
-            return null;
-        }
-
-        try
-        {
-            return MavenMetadataReader.read( metadataFile );
-        }
-        catch (XMLException | IOException e )
-        {
-            // TODO: [monitor] consider a monitor for this event.
-            // TODO: consider a read-redo on monitor return code?
-            log.warn( "Unable to read metadata: {}", metadataFile.getPath(), e );
-            return null;
-        }
+        return readMetadataFile( managedRepository, metadataFile );
     }
 
     public void updateMetadata( ManagedRepositoryContent managedRepository, String logicalResource )
@@ -504,22 +463,10 @@
 
         if ( file.exists() )
         {
-            try
+            ArchivaRepositoryMetadata existingMetadata = readMetadataFile( managedRepository, file );
+            if ( existingMetadata != null )
             {
-                ArchivaRepositoryMetadata existingMetadata = MavenMetadataReader.read( file );
-                if ( existingMetadata != null )
-                {
-                    metadatas.add( existingMetadata );
-                }
-            }
-            catch (XMLException | IOException e )
-            {
-                log.debug( "Could not read metadata at {}. Metadata will be removed.", file.getPath() );
-                try {
-                    file.getStorage().removeAsset(file);
-                } catch (IOException ex) {
-                    log.error("Could not remove asset {}", file.getPath());
-                }
+                metadatas.add( existingMetadata );
             }
         }
 
@@ -563,8 +510,9 @@
     {
 
         StorageAsset metadataFile = managedRepository.getRepository().getAsset( toPath( reference ) );
+        ArchivaRepositoryMetadata existingMetadata = readMetadataFile( managedRepository, metadataFile );
 
-        long lastUpdated = getExistingLastUpdated( metadataFile );
+        long lastUpdated = getExistingLastUpdated( existingMetadata );
 
         ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
         metadata.setGroupId( reference.getGroupId() );
@@ -577,16 +525,9 @@
         // TODO: do we know this information instead?
 //        Set<Plugin> allPlugins = managedRepository.getPlugins( reference );
         Set<Plugin> allPlugins;
-        if ( metadataFile.exists())
+        if ( existingMetadata!=null)
         {
-            try
-            {
-                allPlugins = new LinkedHashSet<Plugin>( MavenMetadataReader.read( metadataFile ).getPlugins() );
-            }
-            catch ( XMLException e )
-            {
-                throw new RepositoryMetadataException( e.getMessage(), e );
-            }
+            allPlugins = new LinkedHashSet<Plugin>( existingMetadata.getPlugins() );
         }
         else
         {
@@ -641,6 +582,16 @@
         checksum.fixChecksums( algorithms );
     }
 
+    public MetadataReader getMetadataReader( ManagedRepositoryContent managedRepository )
+    {
+        if (managedRepository!=null)
+        {
+            return repositoryRegistry.getMetadataReader( managedRepository.getRepository( ).getType( ) );
+        } else {
+            return repositoryRegistry.getMetadataReader( RepositoryType.MAVEN );
+        }
+    }
+
     private void updateMetadataVersions( Collection<String> allVersions, ArchivaRepositoryMetadata metadata )
     {
         // Sort the versions
@@ -732,25 +683,34 @@
         }
     }
 
-    private long getExistingLastUpdated( StorageAsset metadataFile )
+    ArchivaRepositoryMetadata readMetadataFile( ManagedRepositoryContent repository, StorageAsset asset) {
+        MetadataReader reader = getMetadataReader( repository );
+        try
+        {
+            if (asset.exists() && !asset.isContainer())
+            {
+                return reader.read( asset );
+            } else {
+                log.error( "Trying to read metadata from container: {}", asset.getPath( ) );
+                return null;
+            }
+        }
+        catch ( RepositoryMetadataException e )
+        {
+            log.error( "Could not read metadata file {}", asset, e );
+            return null;
+        }
+    }
+
+    private long getExistingLastUpdated( ArchivaRepositoryMetadata metadata )
     {
-        if ( !metadataFile.exists() )
+        if ( metadata==null )
         {
             // Doesn't exist.
             return 0;
         }
 
-        try
-        {
-            ArchivaRepositoryMetadata metadata = MavenMetadataReader.read( metadataFile );
-
-            return getLastUpdated( metadata );
-        }
-        catch (XMLException | IOException e )
-        {
-            // Error.
-            return 0;
-        }
+        return getLastUpdated( metadata );
     }
 
     /**
@@ -773,8 +733,9 @@
         throws LayoutException, RepositoryMetadataException, IOException, ContentNotFoundException
     {
         StorageAsset metadataFile = managedRepository.getRepository().getAsset( toPath( reference ) );
+        ArchivaRepositoryMetadata existingMetadata = readMetadataFile(managedRepository, metadataFile );
 
-        long lastUpdated = getExistingLastUpdated( metadataFile );
+        long lastUpdated = getExistingLastUpdated( existingMetadata );
 
         ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
         metadata.setGroupId( reference.getGroupId() );
@@ -988,4 +949,6 @@
     {
         log.debug( "Configuration event {}", event );
     }
+
+
 }
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/MetadataReaderMock.java b/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/MetadataReaderMock.java
new file mode 100644
index 0000000..c38276f
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/MetadataReaderMock.java
@@ -0,0 +1,49 @@
+package org.apache.archiva.repository.mock;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.archiva.model.ArchivaRepositoryMetadata;
+import org.apache.archiva.repository.RepositoryType;
+import org.apache.archiva.repository.metadata.MetadataReader;
+import org.apache.archiva.repository.metadata.RepositoryMetadataException;
+import org.apache.archiva.repository.storage.StorageAsset;
+import org.springframework.stereotype.Service;
+
+@Service("metadataReader#test")
+public class MetadataReaderMock implements MetadataReader
+{
+    @Override
+    public ArchivaRepositoryMetadata read( StorageAsset asset ) throws RepositoryMetadataException
+    {
+        return new ArchivaRepositoryMetadata();
+    }
+
+    @Override
+    public boolean isValidMetadataPath( String path )
+    {
+        return true;
+    }
+
+    @Override
+    public boolean isValidForType( RepositoryType repositoryType )
+    {
+        return true;
+    }
+}
diff --git a/archiva-modules/archiva-base/archiva-xml-tools/pom.xml b/archiva-modules/archiva-base/archiva-xml-tools/pom.xml
index 6423d26..99ff897 100644
--- a/archiva-modules/archiva-base/archiva-xml-tools/pom.xml
+++ b/archiva-modules/archiva-base/archiva-xml-tools/pom.xml
@@ -38,6 +38,10 @@
       <artifactId>archiva-common</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.apache.archiva</groupId>
+      <artifactId>archiva-storage-api</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.apache.commons</groupId>
        <artifactId>commons-collections4</artifactId>
     </dependency>
diff --git a/archiva-modules/archiva-base/archiva-xml-tools/src/main/java/org/apache/archiva/xml/XMLReader.java b/archiva-modules/archiva-base/archiva-xml-tools/src/main/java/org/apache/archiva/xml/XMLReader.java
index 49073d9..2180daf 100644
--- a/archiva-modules/archiva-base/archiva-xml-tools/src/main/java/org/apache/archiva/xml/XMLReader.java
+++ b/archiva-modules/archiva-base/archiva-xml-tools/src/main/java/org/apache/archiva/xml/XMLReader.java
@@ -19,6 +19,7 @@
  * under the License.
  */
 
+import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.commons.lang3.StringUtils;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -37,6 +38,7 @@
 import javax.xml.xpath.*;
 import java.io.*;
 import java.net.MalformedURLException;
+import java.net.URI;
 import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -78,6 +80,10 @@
     public XMLReader( String type, Path file )
         throws XMLException
     {
+        initWithFile( type, file );
+    }
+
+    private void initWithFile( String type, Path file) throws XMLException {
         if ( !Files.exists(file) )
         {
             throw new XMLException( "file does not exist: " + file.toAbsolutePath() );
@@ -95,7 +101,7 @@
 
         try
         {
-            init( type, file.toUri().toURL() );
+            initWithUrl( type, file.toUri().toURL() );
         }
         catch ( MalformedURLException e )
         {
@@ -103,23 +109,52 @@
         }
     }
 
+    public XMLReader( String type, StorageAsset asset) throws XMLException
+    {
+        if (asset.isFileBased()) {
+            initWithFile( type, asset.getFilePath( ) );
+        } else {
+            URI uri = asset.getStorage( ).getLocation( ).resolve( asset.getPath( ) );
+            try(InputStream in = asset.getReadStream()) {
+                initWithStream( type, uri.toURL( ), in );
+            }
+            catch ( IOException e )
+            {
+                throw new XMLException( "Could not open asset stream of " + uri + ": " + e.getMessage( ), e );
+            }
+        }
+
+
+    }
+
+
     public XMLReader( String type, URL url )
         throws XMLException
     {
-        init( type, url );
+        initWithUrl( type, url );
     }
 
-    private void init( String type, URL url )
+
+    private void initWithUrl( String type, URL url ) throws XMLException {
+        try(InputStream in = url.openStream()) {
+            initWithStream( type, url, in );
+        }
+        catch ( IOException e )
+        {
+            throw new XMLException( "Could not open url " + url + ": " + e.getMessage( ), e );
+        }
+    }
+
+    private void initWithStream( String type, URL url, InputStream in  )
         throws XMLException
     {
         this.documentType = type;
         this.xmlUrl = url;
-
         // SAXReader reader = new SAXReader();
 
 
 
-        try (InputStream in = url.openStream(); Reader reader = new LatinEntityResolutionReader(new BufferedReader(new InputStreamReader(in, "UTF-8"))))
+        try (Reader reader = new LatinEntityResolutionReader(new BufferedReader(new InputStreamReader(in, "UTF-8"))))
         {
 
             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
diff --git a/archiva-modules/archiva-maven/archiva-maven-metadata/pom.xml b/archiva-modules/archiva-maven/archiva-maven-metadata/pom.xml
index 0817913..b3df558 100644
--- a/archiva-modules/archiva-maven/archiva-maven-metadata/pom.xml
+++ b/archiva-modules/archiva-maven/archiva-maven-metadata/pom.xml
@@ -45,6 +45,10 @@
     </dependency>
     <dependency>
       <groupId>org.apache.archiva</groupId>
+      <artifactId>archiva-repository-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.archiva</groupId>
       <artifactId>archiva-xml-tools</artifactId>
     </dependency>
     <dependency>
diff --git a/archiva-modules/archiva-maven/archiva-maven-metadata/src/main/java/org/apache/archiva/maven2/metadata/MavenMetadataReader.java b/archiva-modules/archiva-maven/archiva-maven-metadata/src/main/java/org/apache/archiva/maven2/metadata/MavenMetadataReader.java
index 405c947..05daa17 100644
--- a/archiva-modules/archiva-maven/archiva-maven-metadata/src/main/java/org/apache/archiva/maven2/metadata/MavenMetadataReader.java
+++ b/archiva-modules/archiva-maven/archiva-maven-metadata/src/main/java/org/apache/archiva/maven2/metadata/MavenMetadataReader.java
@@ -21,27 +21,37 @@
 import org.apache.archiva.model.ArchivaRepositoryMetadata;
 import org.apache.archiva.model.Plugin;
 import org.apache.archiva.model.SnapshotVersion;
+import org.apache.archiva.repository.RepositoryType;
+import org.apache.archiva.repository.metadata.MetadataReader;
+import org.apache.archiva.repository.metadata.RepositoryMetadataException;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.archiva.xml.XMLException;
 import org.apache.archiva.xml.XMLReader;
 import org.apache.archiva.xml.XmlUtil;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.math.NumberUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.time.Instant;
 import java.util.Date;
 
 /**
  * @author Olivier Lamy
  * @since 1.4-M3
  */
-public class MavenMetadataReader
+@Service("metadataReader#maven")
+public class MavenMetadataReader implements MetadataReader
 {
+    public static final String MAVEN_METADATA = "maven-metadata.xml";
+
+
     /*
     <?xml version="1.0" encoding="UTF-8"?>
     <metadata modelVersion="1.1.0">
@@ -67,81 +77,121 @@
 
     private static final Logger log = LoggerFactory.getLogger( MavenMetadataReader.class );
 
-    public static ArchivaRepositoryMetadata read(StorageAsset metadataFile) throws XMLException, IOException {
-        if (metadataFile.isFileBased()) {
-            return read(metadataFile.getFilePath());
-        } else {
-            throw new IOException("StorageAsset is not file based");
-        }
-    }
 
     /**
      * Read and return the {@link org.apache.archiva.model.ArchivaRepositoryMetadata} object from the provided xml file.
      *
      * @param metadataFile the maven-metadata.xml file to read.
      * @return the archiva repository metadata object that represents the provided file contents.
-     * @throws XMLException
+     * @throws RepositoryMetadataException if the file cannot be read
      */
-    public static ArchivaRepositoryMetadata read( Path metadataFile )
-            throws XMLException {
+    public ArchivaRepositoryMetadata read( StorageAsset metadataFile )
+            throws RepositoryMetadataException {
 
-        XMLReader xml = new XMLReader( "metadata", metadataFile );
+        XMLReader xml;
+        try
+        {
+            xml = new XMLReader( "metadata", metadataFile );
+        }
+        catch ( XMLException e )
+        {
+            throw new RepositoryMetadataException( "Could not open XML metadata file " + metadataFile, e );
+        }
+        return read( xml, metadataFile.getModificationTime(), metadataFile.getSize() );
+
+    }
+
+    public ArchivaRepositoryMetadata read( Path metadataFile )
+        throws RepositoryMetadataException {
+
+        XMLReader xml;
+        try
+        {
+            xml = new XMLReader( "metadata", metadataFile );
+        }
+        catch ( XMLException e )
+        {
+            log.error( "XML error while reading metadata file {}: {}", metadataFile, e.getMessage(), e );
+            throw new RepositoryMetadataException( "Could not open XML metadata file " + metadataFile, e );
+        }
+        try
+        {
+            return read( xml, Files.getLastModifiedTime( metadataFile ).toInstant(), Files.size( metadataFile ) );
+        }
+        catch ( IOException e )
+        {
+            log.error( "IO Error while reading metadata file {}: {}", metadataFile, e.getMessage(), e );
+            throw new RepositoryMetadataException( "Could not open XML metadata file " + metadataFile, e );
+        }
+
+    }
+
+    private ArchivaRepositoryMetadata read( XMLReader xml, Instant modTime, long fileSize) throws RepositoryMetadataException
+    {
         // invoke this to remove namespaces, see MRM-1136
         xml.removeNamespaces();
 
         ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
 
-        metadata.setGroupId( xml.getElementText( "//metadata/groupId" ) );
-        metadata.setArtifactId( xml.getElementText( "//metadata/artifactId" ) );
-        metadata.setVersion( xml.getElementText( "//metadata/version" ) );
-        Date modTime;
-        try {
-            modTime = new Date(Files.getLastModifiedTime(metadataFile).toMillis());
-        } catch (IOException e) {
-            modTime = new Date();
-            log.error("Could not read modification time of {}", metadataFile);
-        }
-        metadata.setFileLastModified( modTime );
-        try {
-            metadata.setFileSize(Files.size(metadataFile));
-        } catch (IOException e) {
-            metadata.setFileSize( 0 );
-            log.error("Could not read file size of {}", metadataFile);
-        }
-        metadata.setLastUpdated( xml.getElementText( "//metadata/versioning/lastUpdated" ) );
-        metadata.setLatestVersion( xml.getElementText( "//metadata/versioning/latest" ) );
-        metadata.setReleasedVersion( xml.getElementText( "//metadata/versioning/release" ) );
-        metadata.setAvailableVersions( xml.getElementListText( "//metadata/versioning/versions/version" ) );
-
-        Element snapshotElem = xml.getElement( "//metadata/versioning/snapshot" );
-        if ( snapshotElem != null )
+        try
         {
-            SnapshotVersion snapshot = new SnapshotVersion();
-            snapshot.setTimestamp(XmlUtil.getChildText(snapshotElem, "timestamp"));
-            String buildNumber = XmlUtil.getChildText(snapshotElem, "buildNumber");
-            if ( NumberUtils.isCreatable( buildNumber ) )
+            metadata.setGroupId( xml.getElementText( "//metadata/groupId" ) );
+            metadata.setArtifactId( xml.getElementText( "//metadata/artifactId" ) );
+            metadata.setVersion( xml.getElementText( "//metadata/version" ) );
+            metadata.setFileLastModified( Date.from(modTime) );
+            metadata.setFileSize( fileSize );
+            metadata.setLastUpdated( xml.getElementText( "//metadata/versioning/lastUpdated" ) );
+            metadata.setLatestVersion( xml.getElementText( "//metadata/versioning/latest" ) );
+            metadata.setReleasedVersion( xml.getElementText( "//metadata/versioning/release" ) );
+            metadata.setAvailableVersions( xml.getElementListText( "//metadata/versioning/versions/version" ) );
+
+            Element snapshotElem = xml.getElement( "//metadata/versioning/snapshot" );
+            if ( snapshotElem != null )
             {
-                snapshot.setBuildNumber( NumberUtils.toInt( buildNumber ) );
+                SnapshotVersion snapshot = new SnapshotVersion( );
+                snapshot.setTimestamp( XmlUtil.getChildText( snapshotElem, "timestamp" ) );
+                String buildNumber = XmlUtil.getChildText( snapshotElem, "buildNumber" );
+                if ( NumberUtils.isCreatable( buildNumber ) )
+                {
+                    snapshot.setBuildNumber( NumberUtils.toInt( buildNumber ) );
+                }
+                metadata.setSnapshotVersion( snapshot );
             }
-            metadata.setSnapshotVersion( snapshot );
-        }
 
-        for ( Node node : xml.getElementList( "//metadata/plugins/plugin" ) )
-        {
-            if (node instanceof Element) {
-                Element plugin = (Element) node;
-                Plugin p = new Plugin();
-                String prefix = plugin.getElementsByTagName("prefix").item(0).getTextContent().trim();
-                p.setPrefix(prefix);
-                String artifactId = plugin.getElementsByTagName("artifactId").item(0).getTextContent().trim();
-                p.setArtifactId(artifactId);
-                String name = plugin.getElementsByTagName("name").item(0).getTextContent().trim();
-                p.setName(name);
-                metadata.addPlugin(p);
+            for ( Node node : xml.getElementList( "//metadata/plugins/plugin" ) )
+            {
+                if ( node instanceof Element )
+                {
+                    Element plugin = (Element) node;
+                    Plugin p = new Plugin( );
+                    String prefix = plugin.getElementsByTagName( "prefix" ).item( 0 ).getTextContent( ).trim( );
+                    p.setPrefix( prefix );
+                    String artifactId = plugin.getElementsByTagName( "artifactId" ).item( 0 ).getTextContent( ).trim( );
+                    p.setArtifactId( artifactId );
+                    String name = plugin.getElementsByTagName( "name" ).item( 0 ).getTextContent( ).trim( );
+                    p.setName( name );
+                    metadata.addPlugin( p );
+                }
             }
+        } catch ( XMLException e) {
+            throw new RepositoryMetadataException( "XML Error while reading metadata file : " + e.getMessage( ), e );
         }
-
         return metadata;
+    }
 
+    @Override
+    public boolean isValidMetadataPath( String path )
+    {
+        if ( StringUtils.isNotEmpty( path ) ) {
+            return path.endsWith( MAVEN_METADATA );
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean isValidForType( RepositoryType repositoryType )
+    {
+        return RepositoryType.MAVEN.equals( repositoryType );
     }
 }
diff --git a/archiva-modules/archiva-maven/archiva-maven-metadata/src/main/resources/META-INF/spring-context.xml b/archiva-modules/archiva-maven/archiva-maven-metadata/src/main/resources/META-INF/spring-context.xml
new file mode 100644
index 0000000..f954308
--- /dev/null
+++ b/archiva-modules/archiva-maven/archiva-maven-metadata/src/main/resources/META-INF/spring-context.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you 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.
+  -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+           http://www.springframework.org/schema/beans/spring-beans.xsd
+           http://www.springframework.org/schema/context
+           http://www.springframework.org/schema/context/spring-context.xsd"
+       default-lazy-init="true">
+
+  <context:annotation-config/>
+  <context:component-scan base-package="org.apache.archiva.maven2.metadata"/>
+
+</beans>
\ No newline at end of file
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/pom.xml b/archiva-modules/archiva-maven/archiva-maven-proxy/pom.xml
index 657cd0f..eb76b22 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/pom.xml
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/pom.xml
@@ -79,6 +79,11 @@
 
     <!-- Test scope -->
     <dependency>
+      <groupId>org.apache.archiva.maven</groupId>
+      <artifactId>archiva-maven-metadata</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.xmlunit</groupId>
       <artifactId>xmlunit-core</artifactId>
       <scope>test</scope>
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MetadataTransferTest.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MetadataTransferTest.java
index f12a966..47c5bda 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MetadataTransferTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MetadataTransferTest.java
@@ -1098,7 +1098,7 @@
         StringWriter actualContents = new StringWriter();
         FilesystemStorage fsStorage = new FilesystemStorage(actualFile.getParent(), new DefaultFileLockManager());
         StorageAsset actualFileAsset = fsStorage.getAsset(actualFile.getFileName().toString());
-        ArchivaRepositoryMetadata metadata = MavenMetadataReader.read( actualFileAsset );
+        ArchivaRepositoryMetadata metadata = metadataTools.getMetadataReader( null ).read( actualFileAsset );
         RepositoryMetadataWriter.write( metadata, actualContents );
 
         Diff detailedDiff = DiffBuilder.compare( expectedMetadataXml).withTest( actualContents.toString() ).checkForSimilar().build();
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/dependency/tree/maven2/Maven3DependencyTreeBuilder.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/dependency/tree/maven2/Maven3DependencyTreeBuilder.java
index 39ec353..eb490a2 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/dependency/tree/maven2/Maven3DependencyTreeBuilder.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/dependency/tree/maven2/Maven3DependencyTreeBuilder.java
@@ -35,9 +35,9 @@
 import org.apache.archiva.repository.RemoteRepository;
 import org.apache.archiva.repository.RepositoryRegistry;
 import org.apache.archiva.repository.maven2.MavenSystemManager;
+import org.apache.archiva.repository.metadata.RepositoryMetadataException;
 import org.apache.archiva.repository.metadata.base.MetadataTools;
 import org.apache.archiva.repository.storage.StorageAsset;
-import org.apache.archiva.xml.XMLException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.bridge.MavenRepositorySystem;
@@ -56,7 +56,6 @@
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 import javax.inject.Named;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -82,6 +81,10 @@
     private RepositoryPathTranslator pathTranslator;
 
     @Inject
+    @Named("metadataReader#maven")
+    private MavenMetadataReader metadataReader;
+
+    @Inject
     private ProxyConnectorAdmin proxyConnectorAdmin;
 
     @Inject
@@ -252,7 +255,7 @@
                 {
                     try
                     {
-                        ArchivaRepositoryMetadata archivaRepositoryMetadata = MavenMetadataReader.read( metadataFile);
+                        ArchivaRepositoryMetadata archivaRepositoryMetadata = metadataReader.read( metadataFile);
                         int buildNumber = archivaRepositoryMetadata.getSnapshotVersion().getBuildNumber();
                         String timeStamp = archivaRepositoryMetadata.getSnapshotVersion().getTimestamp();
                         // rebuild file name with timestamped version and build number
@@ -269,7 +272,7 @@
                             return managedRepo;
                         }
                     }
-                    catch (XMLException | IOException e )
+                    catch ( RepositoryMetadataException e )
                     {
                         log.warn( "skip fail to find timestamped snapshot pom: {}", e.getMessage() );
                     }
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryStorage.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryStorage.java
index 3725769..b3982b5 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryStorage.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryStorage.java
@@ -42,6 +42,7 @@
 import org.apache.archiva.repository.*;
 import org.apache.archiva.repository.content.PathParser;
 import org.apache.archiva.repository.maven2.MavenSystemManager;
+import org.apache.archiva.repository.metadata.RepositoryMetadataException;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.archiva.xml.XMLException;
 import org.apache.commons.lang3.ArrayUtils;
@@ -87,7 +88,7 @@
 public class Maven2RepositoryStorage
         implements RepositoryStorage {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(Maven2RepositoryStorage.class);
+    private static final Logger log = LoggerFactory.getLogger(Maven2RepositoryStorage.class);
 
     private ModelBuilder builder;
 
@@ -95,6 +96,10 @@
     RepositoryRegistry repositoryRegistry;
 
     @Inject
+    @Named( "metadataReader#maven" )
+    MavenMetadataReader metadataReader;
+
+    @Inject
     @Named("repositoryPathTranslator#maven2")
     private RepositoryPathTranslator pathTranslator;
 
@@ -166,7 +171,7 @@
                     readMetadataRequest.getProjectId(), artifactVersion,
                     METADATA_FILENAME);
             try {
-                ArchivaRepositoryMetadata metadata = MavenMetadataReader.read(metadataFile);
+                ArchivaRepositoryMetadata metadata = metadataReader.read(metadataFile);
 
                 // re-adjust to timestamp if present, otherwise retain the original -SNAPSHOT filename
                 SnapshotVersion snapshotVersion = metadata.getSnapshotVersion();
@@ -176,9 +181,9 @@
                     artifactVersion =
                             artifactVersion + snapshotVersion.getTimestamp() + "-" + snapshotVersion.getBuildNumber();
                 }
-            } catch (XMLException | IOException e) {
+            } catch ( RepositoryMetadataException e) {
                 // unable to parse metadata - LOGGER it, and continue with the version as the original SNAPSHOT version
-                LOGGER.warn("Invalid metadata: {} - {}", metadataFile, e.getMessage());
+                log.warn("Invalid metadata: {} - {}", metadataFile, e.getMessage());
             }
         }
 
@@ -236,7 +241,7 @@
         // MRM-1411
         req.setModelResolver(
                 new RepositoryModelResolver(managedRepository, pathTranslator, wagonFactory, remoteRepositories,
-                        networkProxies, managedRepository, mavenSystemManager));
+                        networkProxies, managedRepository, mavenSystemManager, metadataReader));
 
         Model model;
         try {
@@ -255,7 +260,7 @@
                         || problem.getException() instanceof NoSuchFileException
                 ) && e.getModelId() != null &&
                         !e.getModelId().equals(problem.getModelId()))) {
-                    LOGGER.warn("The artifact's parent POM file '{}' cannot be resolved. "
+                    log.warn("The artifact's parent POM file '{}' cannot be resolved. "
                             + "Using defaults for project version metadata..", file);
 
                     ProjectVersionMetadata metadata = new ProjectVersionMetadata();
@@ -514,15 +519,15 @@
                                 readMetadataRequest.getProjectId(), readMetadataRequest.getProjectVersion(),
                                 path));
                     } catch (Exception e) {
-                        LOGGER.debug("Could not create metadata for {}:  {}", path, e.getMessage(), e);
+                        log.debug("Could not create metadata for {}:  {}", path, e.getMessage(), e);
                         return Try.<ArtifactMetadata>failure(e);
                     }
                 }
         ).collect(Collectors.groupingBy(Try::isSuccess));
         if (result.containsKey(Boolean.FALSE) && result.get(Boolean.FALSE).size() > 0 && (!result.containsKey(Boolean.TRUE) || result.get(Boolean.TRUE).size() == 0)) {
-            LOGGER.error("Could not get artifact metadata. Directory: {}. Number of errors {}.", dir, result.get(Boolean.FALSE).size());
+            log.error("Could not get artifact metadata. Directory: {}. Number of errors {}.", dir, result.get(Boolean.FALSE).size());
             Try<ArtifactMetadata> failure = result.get(Boolean.FALSE).get(0);
-            LOGGER.error("Sample exception {}", failure.getError().getMessage(), failure.getError());
+            log.error("Sample exception {}", failure.getError().getMessage(), failure.getError());
             throw new RepositoryStorageRuntimeException(readMetadataRequest.getRepositoryId(), "Could not retrieve metadata of the files");
         } else {
             if (!result.containsKey(Boolean.TRUE) || result.get(Boolean.TRUE) == null) {
@@ -661,7 +666,8 @@
 
     @Override
     public String getFilePathWithVersion(final String requestPath, ManagedRepositoryContent managedRepositoryContent)
-            throws RelocationException, XMLException, IOException {
+            throws RelocationException
+    {
 
         if (StringUtils.endsWith(requestPath, METADATA_FILENAME)) {
             return getFilePath(requestPath, managedRepositoryContent.getRepository());
@@ -686,7 +692,16 @@
             if (!metadataFile.exists()) {
                 return filePath;
             }
-            ArchivaRepositoryMetadata archivaRepositoryMetadata = MavenMetadataReader.read(metadataFile);
+            ArchivaRepositoryMetadata archivaRepositoryMetadata = null;
+            try
+            {
+                archivaRepositoryMetadata = metadataReader.read(metadataFile);
+            }
+            catch ( RepositoryMetadataException e )
+            {
+                log.error( "Could not read metadata {}", e.getMessage( ), e );
+                return filePath;
+            }
             int buildNumber = archivaRepositoryMetadata.getSnapshotVersion().getBuildNumber();
             String timestamp = archivaRepositoryMetadata.getSnapshotVersion().getTimestamp();
 
@@ -748,12 +763,12 @@
         try {
             metadata.setMd5(checksummedFile.calculateChecksum(ChecksumAlgorithm.MD5));
         } catch (IOException e) {
-            LOGGER.error("Unable to checksum file {}: {},MD5", file, e.getMessage());
+            log.error("Unable to checksum file {}: {},MD5", file, e.getMessage());
         }
         try {
             metadata.setSha1(checksummedFile.calculateChecksum(ChecksumAlgorithm.SHA1));
         } catch (IOException e) {
-            LOGGER.error("Unable to checksum file {}: {},SHA1", file, e.getMessage());
+            log.error("Unable to checksum file {}: {},SHA1", file, e.getMessage());
         }
         metadata.setSize(file.getSize());
     }
@@ -806,9 +821,10 @@
         StorageAsset metadataFile = directory.resolve(METADATA_FILENAME);
         if (metadataFile.exists()) {
             try {
-                metadata = MavenMetadataReader.read(metadataFile);
-            } catch (XMLException | IOException e) {
-                // ignore missing or invalid metadata
+                metadata = metadataReader.read(metadataFile);
+            } catch ( RepositoryMetadataException e )
+            {
+                // Ignore missing or invalid metadata
             }
         }
         return metadata;
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/RepositoryModelResolver.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/RepositoryModelResolver.java
index 9b1a410..8655593 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/RepositoryModelResolver.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/RepositoryModelResolver.java
@@ -32,8 +32,8 @@
 import org.apache.archiva.repository.RemoteRepository;
 import org.apache.archiva.repository.RepositoryCredentials;
 import org.apache.archiva.repository.maven2.MavenSystemManager;
+import org.apache.archiva.repository.metadata.RepositoryMetadataException;
 import org.apache.archiva.repository.storage.StorageAsset;
-import org.apache.archiva.xml.XMLException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.auth.UsernamePasswordCredentials;
 import org.apache.maven.model.Dependency;
@@ -65,7 +65,6 @@
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -95,21 +94,24 @@
 
     private MavenSystemManager mavenSystemManager;
 
+    private MavenMetadataReader metadataReader;
+
 
 
     private ManagedRepository managedRepository;
 
-    public RepositoryModelResolver(StorageAsset basedir, RepositoryPathTranslator pathTranslator )
+    public RepositoryModelResolver(StorageAsset basedir, RepositoryPathTranslator pathTranslator)
     {
         this.basedir = basedir;
 
         this.pathTranslator = pathTranslator;
+
     }
 
     public RepositoryModelResolver(ManagedRepository managedRepository, RepositoryPathTranslator pathTranslator,
                                    WagonFactory wagonFactory, List<RemoteRepository> remoteRepositories,
                                    Map<String, NetworkProxy> networkProxiesMap, ManagedRepository targetRepository,
-                                   MavenSystemManager mavenSystemManager)
+                                   MavenSystemManager mavenSystemManager, MavenMetadataReader metadataReader)
     {
         this( managedRepository.getAsset(""), pathTranslator );
 
@@ -129,6 +131,7 @@
         this.versionRangeResolver = mavenSystemManager.getLocator().getService(VersionRangeResolver.class);
 
         this.mavenSystemManager = mavenSystemManager;
+        this.metadataReader = metadataReader;
     }
 
 
@@ -236,7 +239,7 @@
         {
             try
             {
-                ArchivaRepositoryMetadata archivaRepositoryMetadata = MavenMetadataReader.read( mavenMetadata);
+                ArchivaRepositoryMetadata archivaRepositoryMetadata = metadataReader.read( mavenMetadata );
                 SnapshotVersion snapshotVersion = archivaRepositoryMetadata.getSnapshotVersion();
                 if ( snapshotVersion != null )
                 {
@@ -258,7 +261,7 @@
                     }
                 }
             }
-            catch (XMLException e )
+            catch ( RepositoryMetadataException e )
             {
                 log.warn( "fail to read {}, {}", mavenMetadata.toAbsolutePath(), e.getCause() );
             }
@@ -286,7 +289,7 @@
     public ModelResolver newCopy()
     {
         return new RepositoryModelResolver( managedRepository,  pathTranslator, wagonFactory, remoteRepositories, 
-                                            networkProxyMap, targetRepository, mavenSystemManager);
+                                            networkProxyMap, targetRepository, mavenSystemManager, metadataReader);
     }
 
     // FIXME: we need to do some refactoring, we cannot re-use the proxy components of archiva-proxy in maven2-repository
@@ -294,7 +297,7 @@
     private boolean getModelFromProxy( RemoteRepository remoteRepository, String groupId, String artifactId,
                                        String version, String filename )
         throws AuthorizationException, TransferFailedException, ResourceDoesNotExistException, WagonFactoryException,
-        XMLException, IOException
+        IOException, RepositoryMetadataException
     {
         boolean success = false;
         Path tmpMd5 = null;
@@ -339,7 +342,7 @@
 
                         log.debug( "Successfully downloaded metadata." );
 
-                        ArchivaRepositoryMetadata metadata = MavenMetadataReader.read( tmpMetadataResource );
+                        ArchivaRepositoryMetadata metadata = metadataReader.read( tmpMetadataResource );
 
                         // re-adjust to timestamp if present, otherwise retain the original -SNAPSHOT filename
                         SnapshotVersion snapshotVersion = metadata.getSnapshotVersion();
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMerger.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMerger.java
index 60baaf4..a37ced0 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMerger.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMerger.java
@@ -41,7 +41,6 @@
 import org.apache.archiva.repository.storage.FilesystemAsset;
 import org.apache.archiva.repository.storage.FilesystemStorage;
 import org.apache.archiva.repository.storage.StorageAsset;
-import org.apache.archiva.xml.XMLException;
 import org.apache.commons.io.FileUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -66,7 +65,11 @@
     implements RepositoryMerger
 {
 
-    private Logger log = LoggerFactory.getLogger( getClass() );
+    @Inject
+    @Named("metadataReader#maven")
+    private MavenMetadataReader metadataReader;
+
+    private static final Logger log = LoggerFactory.getLogger( Maven2RepositoryMerger.class );
 
     private static final Comparator<ArtifactMetadata> META_COMPARATOR = Comparator.comparing(ArtifactMetadata::getNamespace)
             .thenComparing(ArtifactMetadata::getProject)
@@ -391,14 +394,7 @@
         ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
         if ( Files.exists(metadataFile) )
         {
-            try
-            {
-                metadata = MavenMetadataReader.read( metadataFile );
-            }
-            catch (XMLException e )
-            {
-                throw new RepositoryMetadataException( e.getMessage(), e );
-            }
+            metadata = metadataReader.read( metadataFile );
         }
         return metadata;
     }
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/configuration/StubConfiguration.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/configuration/StubConfiguration.java
index f1f3d5c..f7459c5 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/configuration/StubConfiguration.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/configuration/StubConfiguration.java
@@ -35,6 +35,10 @@
 {
     private Configuration configuration = new Configuration();
 
+    StubConfiguration() {
+        configuration.setRepositoryScanning( new RepositoryScanningConfiguration() );
+    }
+
     @Override
     public Configuration getConfiguration()
     {
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/MavenRepositoryMetadataReaderTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/MavenRepositoryMetadataReaderTest.java
index 769be5e..17aef31 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/MavenRepositoryMetadataReaderTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/MavenRepositoryMetadataReaderTest.java
@@ -23,13 +23,12 @@
 import org.apache.archiva.maven2.metadata.MavenMetadataReader;
 import org.apache.archiva.model.ArchivaRepositoryMetadata;
 import org.apache.archiva.model.Plugin;
+import org.apache.archiva.repository.metadata.RepositoryMetadataException;
 import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner;
-import org.apache.archiva.xml.XMLException;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
@@ -47,10 +46,12 @@
 
     @Test
     public void testGroupMetadata()
-            throws XMLException, IOException {
+        throws RepositoryMetadataException
+    {
         Path metadataFile = defaultRepoDir.resolve( "org/apache/maven/plugins/maven-metadata.xml" );
 
-        ArchivaRepositoryMetadata metadata = MavenMetadataReader.read( metadataFile );
+        MavenMetadataReader metadataReader = new MavenMetadataReader( );
+        ArchivaRepositoryMetadata metadata = metadataReader.read( metadataFile );
 
         assertNotNull( metadata );
         assertEquals( "org.apache.maven.plugins", metadata.getGroupId() );
@@ -81,10 +82,12 @@
 
     @Test
     public void testProjectMetadata()
-            throws XMLException, IOException {
+        throws RepositoryMetadataException
+    {
         Path metadataFile = defaultRepoDir.resolve( "org/apache/maven/shared/maven-downloader/maven-metadata.xml" );
 
-        ArchivaRepositoryMetadata metadata = MavenMetadataReader.read( metadataFile);
+        MavenMetadataReader metadataReader = new MavenMetadataReader( );
+        ArchivaRepositoryMetadata metadata = metadataReader.read( metadataFile );
 
         assertNotNull( metadata );
         assertEquals( "org.apache.maven.shared", metadata.getGroupId() );
@@ -98,10 +101,12 @@
 
     @Test
     public void testProjectVersionMetadata()
-            throws XMLException, IOException {
+        throws RepositoryMetadataException
+    {
         Path metadataFile = defaultRepoDir.resolve( "org/apache/apache/5-SNAPSHOT/maven-metadata.xml" );
 
-        ArchivaRepositoryMetadata metadata = MavenMetadataReader.read( metadataFile );
+        MavenMetadataReader metadataReader = new MavenMetadataReader( );
+        ArchivaRepositoryMetadata metadata = metadataReader.read(metadataFile );
 
         assertNotNull( metadata );
         assertEquals( "org.apache", metadata.getGroupId() );
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/metadata/RepositoryMetadataReaderTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/metadata/RepositoryMetadataReaderTest.java
index a028140..634d13d 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/metadata/RepositoryMetadataReaderTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/metadata/RepositoryMetadataReaderTest.java
@@ -23,11 +23,9 @@
 import org.apache.archiva.maven2.metadata.MavenMetadataReader;
 import org.apache.archiva.model.ArchivaRepositoryMetadata;
 import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner;
-import org.apache.archiva.xml.XMLException;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 
@@ -42,11 +40,14 @@
 {
     @Test
     public void testLoadSimple()
-            throws XMLException, IOException {
+        throws RepositoryMetadataException
+    {
         Path defaultRepoDir = Paths.get( "src/test/repositories/default-repository" );
         Path metadataFile = defaultRepoDir.resolve( "org/apache/maven/shared/maven-downloader/maven-metadata.xml" );
 
-        ArchivaRepositoryMetadata metadata = MavenMetadataReader.read( metadataFile);
+        MavenMetadataReader metadataReader = new MavenMetadataReader( );
+
+        ArchivaRepositoryMetadata metadata = metadataReader.read( metadataFile );
 
         assertNotNull( metadata );
         assertEquals( "Group Id", "org.apache.maven.shared", metadata.getGroupId() );
@@ -59,11 +60,13 @@
 
     @Test
     public void testLoadComplex()
-            throws XMLException, IOException {
+        throws RepositoryMetadataException
+    {
         Path defaultRepoDir = Paths.get( "src/test/repositories/default-repository" );
         Path metadataFile = defaultRepoDir.resolve( "org/apache/maven/samplejar/maven-metadata.xml" );
+        MavenMetadataReader metadataReader = new MavenMetadataReader( );
 
-        ArchivaRepositoryMetadata metadata = MavenMetadataReader.read( metadataFile );
+        ArchivaRepositoryMetadata metadata = metadataReader.read( metadataFile );
 
         assertNotNull( metadata );
         assertEquals( "Group Id", "org.apache.maven", metadata.getGroupId() );
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java
index 3bb2a87..7899fdf 100644
--- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java
@@ -42,6 +42,8 @@
 import org.apache.archiva.repository.ReleaseScheme;
 import org.apache.archiva.repository.RepositoryException;
 import org.apache.archiva.repository.RepositoryNotFoundException;
+import org.apache.archiva.repository.RepositoryRegistry;
+import org.apache.archiva.repository.metadata.MetadataReader;
 import org.apache.archiva.repository.metadata.base.MetadataTools;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.archiva.repository.storage.StorageUtil;
@@ -87,6 +89,9 @@
     ProxyRegistry proxyRegistry;
 
     @Inject
+    RepositoryRegistry repositoryRegistry;
+
+    @Inject
     @Named( value = "browse#versionMetadata" )
     private Cache<String, ProjectVersionMetadata> versionMetadataCache;
 
@@ -919,30 +924,24 @@
                     StorageAsset metadataFile = file.getStorage().getAsset(file.getParent().getPath()+"/"+MetadataTools.MAVEN_METADATA );
                     if ( metadataFile.exists() )
                     {
-                        try
-                        {
-                            ArchivaRepositoryMetadata archivaRepositoryMetadata =
-                                MavenMetadataReader.read( metadataFile );
-                            int buildNumber = archivaRepositoryMetadata.getSnapshotVersion().getBuildNumber();
-                            String timeStamp = archivaRepositoryMetadata.getSnapshotVersion().getTimestamp();
-                            // rebuild file name with timestamped version and build number
-                            String timeStampFileName = new StringBuilder( artifactId ).append( '-' ) //
-                                .append( StringUtils.remove( version, "-" + VersionUtil.SNAPSHOT ) ) //
-                                .append( '-' ).append( timeStamp ) //
-                                .append( '-' ).append( Integer.toString( buildNumber ) ) //
-                                .append( ( StringUtils.isEmpty( classifier ) ? "" : "-" + classifier ) ) //
-                                .append( ".jar" ).toString();
+                        MetadataReader metadataReader = repositoryRegistry.getMetadataReader( managedRepositoryContent.getRepository( ).getType( ) );
+                        ArchivaRepositoryMetadata archivaRepositoryMetadata =
+                            metadataReader.read( metadataFile );
+                        int buildNumber = archivaRepositoryMetadata.getSnapshotVersion().getBuildNumber();
+                        String timeStamp = archivaRepositoryMetadata.getSnapshotVersion().getTimestamp();
+                        // rebuild file name with timestamped version and build number
+                        String timeStampFileName = new StringBuilder( artifactId ).append( '-' ) //
+                            .append( StringUtils.remove( version, "-" + VersionUtil.SNAPSHOT ) ) //
+                            .append( '-' ).append( timeStamp ) //
+                            .append( '-' ).append( Integer.toString( buildNumber ) ) //
+                            .append( ( StringUtils.isEmpty( classifier ) ? "" : "-" + classifier ) ) //
+                            .append( ".jar" ).toString();
 
-                            StorageAsset timeStampFile = file.getStorage().getAsset(file.getParent().getPath() + "/" + timeStampFileName );
-                            log.debug( "try to find timestamped snapshot version file: {}", timeStampFile.getPath() );
-                            if ( timeStampFile.exists() )
-                            {
-                                return true;
-                            }
-                        }
-                        catch (XMLException | IOException e )
+                        StorageAsset timeStampFile = file.getStorage().getAsset(file.getParent().getPath() + "/" + timeStampFileName );
+                        log.debug( "try to find timestamped snapshot version file: {}", timeStampFile.getPath() );
+                        if ( timeStampFile.exists() )
                         {
-                            log.warn( "skip fail to find timestamped snapshot file: {}", e.getMessage() );
+                            return true;
                         }
                     }
                 }
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java
index 55c9995..8cf4ec0 100644
--- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java
@@ -50,6 +50,7 @@
 import org.apache.archiva.repository.RepositoryException;
 import org.apache.archiva.repository.RepositoryNotFoundException;
 import org.apache.archiva.repository.RepositoryRegistry;
+import org.apache.archiva.repository.RepositoryType;
 import org.apache.archiva.repository.storage.RepositoryStorage;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.archiva.repository.storage.StorageUtil;
@@ -404,7 +405,7 @@
             String timestamp = null;
 
             StorageAsset versionMetadataFile = target.getAsset(path + "/" + MetadataTools.MAVEN_METADATA );
-            /* unused */ getMetadata( versionMetadataFile );
+            /* unused */ getMetadata( targetRepository.getRepository().getType(), versionMetadataFile );
 
             if ( !targetDir.exists() )
             {
@@ -454,7 +455,7 @@
             // explicitly update only if metadata-updater consumer is not enabled!
             if ( !archivaAdministration.getKnownContentConsumers().contains( "metadata-updater" ) )
             {
-                updateProjectMetadata( target, targetDir, lastUpdatedTimestamp, timestamp, newBuildNumber,
+                updateProjectMetadata( target.getType(), target, targetDir, lastUpdatedTimestamp, timestamp, newBuildNumber,
                                        fixChecksums, artifactTransferRequest );
 
 
@@ -505,20 +506,13 @@
         }
     }
 
-    private ArchivaRepositoryMetadata getMetadata( StorageAsset metadataFile )
+    private ArchivaRepositoryMetadata getMetadata( RepositoryType repositoryType, StorageAsset metadataFile )
         throws RepositoryMetadataException
     {
         ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
         if ( metadataFile.exists() )
         {
-            try
-            {
-                metadata = MavenMetadataReader.read( metadataFile.getFilePath() );
-            }
-            catch (XMLException e )
-            {
-                throw new RepositoryMetadataException( e.getMessage(), e );
-            }
+            metadata = repositoryRegistry.getMetadataReader( repositoryType ).read( metadataFile );
         }
         return metadata;
     }
@@ -553,7 +547,7 @@
         }
     }
 
-    private void updateProjectMetadata( RepositoryStorage storage, StorageAsset targetPath, Date lastUpdatedTimestamp, String timestamp, int buildNumber,
+    private void updateProjectMetadata( RepositoryType repositoryType, RepositoryStorage storage, StorageAsset targetPath, Date lastUpdatedTimestamp, String timestamp, int buildNumber,
                                         boolean fixChecksums, ArtifactTransferRequest artifactTransferRequest )
         throws RepositoryMetadataException
     {
@@ -563,7 +557,7 @@
         StorageAsset projectDir = targetPath.getParent();
         StorageAsset projectMetadataFile = storage.getAsset( projectDir.getPath()+"/"+MetadataTools.MAVEN_METADATA );
 
-        ArchivaRepositoryMetadata projectMetadata = getMetadata( projectMetadataFile );
+        ArchivaRepositoryMetadata projectMetadata = getMetadata( repositoryType, projectMetadataFile );
 
         if ( projectMetadataFile.exists() )
         {
@@ -854,7 +848,7 @@
                         repository.deleteArtifact( artifactRef );
                     }
                     StorageAsset metadataFile = getMetadata( repo, targetPath.getPath() );
-                    ArchivaRepositoryMetadata metadata = getMetadata( metadataFile );
+                    ArchivaRepositoryMetadata metadata = getMetadata( repository.getRepository().getType(), metadataFile );
 
                     updateMetadata( metadata, metadataFile, lastUpdatedTimestamp, artifact );
                 }
diff --git a/archiva-modules/archiva-web/archiva-web-common/src/main/java/org/apache/archiva/web/api/DefaultFileUploadService.java b/archiva-modules/archiva-web/archiva-web-common/src/main/java/org/apache/archiva/web/api/DefaultFileUploadService.java
index a3f8c09..3b3fe4e 100644
--- a/archiva-modules/archiva-web/archiva-web-common/src/main/java/org/apache/archiva/web/api/DefaultFileUploadService.java
+++ b/archiva-modules/archiva-web/archiva-web-common/src/main/java/org/apache/archiva/web/api/DefaultFileUploadService.java
@@ -36,9 +36,13 @@
 import org.apache.archiva.model.ArtifactReference;
 import org.apache.archiva.model.SnapshotVersion;
 import org.apache.archiva.components.taskqueue.TaskQueueException;
+import org.apache.archiva.repository.Repository;
 import org.apache.archiva.repository.RepositoryException;
 import org.apache.archiva.repository.RepositoryNotFoundException;
+import org.apache.archiva.repository.RepositoryRegistry;
+import org.apache.archiva.repository.RepositoryType;
 import org.apache.archiva.repository.content.base.ArtifactUtil;
+import org.apache.archiva.repository.metadata.MetadataReader;
 import org.apache.archiva.repository.metadata.base.MetadataTools;
 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
 import org.apache.archiva.repository.metadata.base.RepositoryMetadataWriter;
@@ -113,6 +117,9 @@
     @Named(value = "archivaTaskScheduler#repository")
     private ArchivaTaskScheduler<RepositoryTask> scheduler;
 
+    @Inject
+    private RepositoryRegistry repositoryRegistry;
+
     private String getStringValue(MultipartBody multipartBody, String attachmentId)
             throws IOException {
         Attachment attachment = multipartBody.getAttachment(attachmentId);
@@ -527,11 +534,10 @@
             throws RepositoryMetadataException {
         ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
         if (metadataFile.exists()) {
-            try {
-                metadata = MavenMetadataReader.read(metadataFile);
-            } catch (XMLException | IOException e) {
-                throw new RepositoryMetadataException(e.getMessage(), e);
-            }
+            Repository repo = repositoryRegistry.getRepositoryOfAsset( metadataFile );
+            RepositoryType type = repo == null ? RepositoryType.MAVEN : repo.getType( );
+            MetadataReader metadataReader = repositoryRegistry.getMetadataReader( type );
+            metadata = metadataReader.read(metadataFile);
         }
         return metadata;
     }
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java
index b9bd4ad..7c56f65 100644
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java
+++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java
@@ -66,6 +66,7 @@
 import org.apache.archiva.repository.RepositoryGroup;
 import org.apache.archiva.repository.RepositoryRegistry;
 import org.apache.archiva.repository.RepositoryRequestInfo;
+import org.apache.archiva.repository.storage.FilesystemAsset;
 import org.apache.archiva.repository.storage.FilesystemStorage;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.archiva.metadata.audit.AuditListener;
@@ -103,6 +104,7 @@
 import javax.inject.Named;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
+import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
@@ -340,19 +342,20 @@
                             try
                             {
                                 Path metadataFile = Paths.get( resourceAbsPath );
-                                ArchivaRepositoryMetadata repoMetadata = MavenMetadataReader.read( metadataFile );
+                                FilesystemStorage storage = new FilesystemStorage( metadataFile.getParent( ), new DefaultFileLockManager( ) );
+                                ArchivaRepositoryMetadata repoMetadata = repositoryRegistry.getMetadataReader( repoGroup.getType( ) ).read( storage.getAsset( metadataFile.getFileName().toString() ) );
                                 mergedMetadata = RepositoryMetadataMerge.merge( mergedMetadata, repoMetadata );
                             }
-                            catch (XMLException e )
-                            {
-                                throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
-                                                        "Error occurred while reading metadata file." );
-                            }
                             catch ( RepositoryMetadataException r )
                             {
                                 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                                                         "Error occurred while merging metadata file." );
                             }
+                            catch ( IOException e )
+                            {
+                                throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                                    "Error occurred while merging metadata file." );
+                            }
                         }
 
                         try
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/RepositoryServletRepositoryGroupTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/RepositoryServletRepositoryGroupTest.java
index b634bfd..ed44abf 100644
--- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/RepositoryServletRepositoryGroupTest.java
+++ b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/RepositoryServletRepositoryGroupTest.java
@@ -259,7 +259,8 @@
 
         Path returnedMetadata = getProjectBase().resolve( "target/test-classes/retrievedMetadataFile.xml" );
         org.apache.archiva.common.utils.FileUtils.writeStringToFile( returnedMetadata, Charset.defaultCharset(), response.getContentAsString() );
-        ArchivaRepositoryMetadata metadata = MavenMetadataReader.read( returnedMetadata );
+        MavenMetadataReader metadataReader = new MavenMetadataReader( );
+        ArchivaRepositoryMetadata metadata = metadataReader.read( returnedMetadata );
 
         assertResponseOK( response );