You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by ma...@apache.org on 2019/08/27 20:09:31 UTC

[archiva] branch feature/storage_refactoring updated: Migrating to primaryTypes and modifying dependencies

This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a commit to branch feature/storage_refactoring
in repository https://gitbox.apache.org/repos/asf/archiva.git


The following commit(s) were added to refs/heads/feature/storage_refactoring by this push:
     new 31fd0d9  Migrating to primaryTypes and modifying dependencies
31fd0d9 is described below

commit 31fd0d917e6678dc3a39f5cf3b2904ddcae67985
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Tue Aug 27 22:09:09 2019 +0200

    Migrating to primaryTypes and modifying dependencies
---
 .../storage/maven2/Maven2RepositoryStorage.java    |    2 +-
 ...sitoryMetadataResolverMRM1411RepoGroupTest.java |    2 +-
 ...aven2RepositoryMetadataResolverMRM1411Test.java |    2 +-
 .../Maven2RepositoryMetadataResolverTest.java      |    2 +-
 .../rest/services/DefaultRepositoriesService.java  |    2 +-
 .../apache/archiva/metadata/model/Dependency.java  |   25 +-
 .../org/apache/archiva/metadata/model/License.java |   18 +-
 .../apache/archiva/metadata/model/MailingList.java |   18 +-
 .../repository/AbstractMetadataRepositoryTest.java |   10 +-
 .../cassandra/CassandraMetadataRepository.java     |    4 +-
 .../repository/file/FileMetadataRepository.java    |    6 +-
 .../metadata/repository/jcr/JcrConstants.java      |    5 +
 .../repository/jcr/JcrMetadataRepository.java      | 2171 +++++++++-----------
 .../archiva/metadata/repository/jcr/jcr-schema.cnd |   33 +-
 14 files changed, 1024 insertions(+), 1276 deletions(-)

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 57c4a6b..b9040a6 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
@@ -351,7 +351,7 @@ public class Maven2RepositoryStorage
                     new org.apache.archiva.metadata.model.Dependency();
             newDependency.setArtifactId(dependency.getArtifactId());
             newDependency.setClassifier(dependency.getClassifier());
-            newDependency.setGroupId(dependency.getGroupId());
+            newDependency.setNamespace(dependency.getGroupId());
             newDependency.setOptional(dependency.isOptional());
             newDependency.setScope(dependency.getScope());
             newDependency.setSystemPath(dependency.getSystemPath());
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverMRM1411RepoGroupTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverMRM1411RepoGroupTest.java
index 2cb7fe4..8aaf3d8 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverMRM1411RepoGroupTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverMRM1411RepoGroupTest.java
@@ -449,7 +449,7 @@ public class Maven2RepositoryMetadataResolverMRM1411RepoGroupTest
         assertEquals( artifactId, dependency.getArtifactId() );
         assertEquals( "jar", dependency.getType() );
         assertEquals( version, dependency.getVersion() );
-        assertEquals( groupId, dependency.getGroupId() );
+        assertEquals( groupId, dependency.getNamespace() );
         assertEquals( scope, dependency.getScope() );
         assertNull( dependency.getClassifier() );
         assertNull( dependency.getSystemPath() );
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverMRM1411Test.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverMRM1411Test.java
index 65213b7..3bb6146 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverMRM1411Test.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverMRM1411Test.java
@@ -345,7 +345,7 @@ public class Maven2RepositoryMetadataResolverMRM1411Test
         assertEquals( artifactId, dependency.getArtifactId() );
         assertEquals( "jar", dependency.getType() );
         assertEquals( version, dependency.getVersion() );
-        assertEquals( groupId, dependency.getGroupId() );
+        assertEquals( groupId, dependency.getNamespace() );
         assertEquals( scope, dependency.getScope() );
         assertNull( dependency.getClassifier() );
         assertNull( dependency.getSystemPath() );
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverTest.java
index 47d6555..77b8aa1 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverTest.java
@@ -434,7 +434,7 @@ public class Maven2RepositoryMetadataResolverTest
         assertEquals( artifactId, dependency.getArtifactId() );
         assertEquals( "jar", dependency.getType() );
         assertEquals( version, dependency.getVersion() );
-        assertEquals( groupId, dependency.getGroupId() );
+        assertEquals( groupId, dependency.getNamespace() );
         assertEquals( scope, dependency.getScope() );
         assertNull( dependency.getClassifier() );
         assertNull( dependency.getSystemPath() );
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 fd7ae90..b92f36b 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
@@ -834,7 +834,7 @@ public class DefaultRepositoriesService
                 if ( !targetPath.exists() )
                 {
                     //throw new ContentNotFoundException(
-                    //    artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion() );
+                    //    artifact.getNamespace() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion() );
                     log.warn( "targetPath {} not found skip file deletion", targetPath );
                     return false;
                 }
diff --git a/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/Dependency.java b/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/Dependency.java
index 15bcf24..e00f51d 100644
--- a/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/Dependency.java
+++ b/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/Dependency.java
@@ -64,7 +64,12 @@ public class Dependency
     /**
      * The Maven group ID of the dependency.
      */
-    private String groupId;
+    private String namespace;
+
+    /**
+     * The project id
+     */
+    private String projectId;
 
     /**
      * The version of the artifact to depend on. If this refers to a project version then the repository implementation
@@ -127,9 +132,9 @@ public class Dependency
         this.artifactId = artifactId;
     }
 
-    public void setGroupId( String groupId )
+    public void setNamespace(String groupId )
     {
-        this.groupId = groupId;
+        this.namespace = groupId;
     }
 
     public void setVersion( String version )
@@ -147,9 +152,17 @@ public class Dependency
         return artifactId;
     }
 
-    public String getGroupId()
+    public String getNamespace()
     {
-        return groupId;
+        return namespace;
+    }
+
+    public String getProjectId() {
+        return projectId;
+    }
+
+    public void setProjectId(String projectId) {
+        this.projectId = projectId;
     }
 
     @Override
@@ -163,7 +176,7 @@ public class Dependency
         sb.append( ", systemPath='" ).append( systemPath ).append( '\'' );
         sb.append( ", type='" ).append( type ).append( '\'' );
         sb.append( ", artifactId='" ).append( artifactId ).append( '\'' );
-        sb.append( ", groupId='" ).append( groupId ).append( '\'' );
+        sb.append( ", namespace='" ).append(namespace).append( '\'' );
         sb.append( ", version='" ).append( version ).append( '\'' );
         sb.append( '}' );
         return sb.toString();
diff --git a/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/License.java b/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/License.java
index 1c9ef6c..961bd6e 100644
--- a/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/License.java
+++ b/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/License.java
@@ -27,7 +27,7 @@ import java.io.Serializable;
  */
 @XmlRootElement(name = "license")
 public class License
-    implements Serializable
+    implements Serializable, Comparable<License>
 {
     /**
      * The name of the license.
@@ -39,6 +39,8 @@ public class License
      */
     private String url;
 
+    private Integer index = 0;
+
     public License( String name, String url )
     {
         this.name = name;
@@ -109,4 +111,18 @@ public class License
     {
         return "License{" + "name='" + name + '\'' + ", url='" + url + '\'' + '}';
     }
+
+    public Integer getIndex() {
+        return index;
+    }
+
+    public void setIndex(int index) {
+        this.index = index;
+    }
+
+
+    @Override
+    public int compareTo(License o) {
+        return this.index.compareTo(o.getIndex());
+    }
 }
diff --git a/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/MailingList.java b/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/MailingList.java
index 0297ebf..7a934c3 100644
--- a/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/MailingList.java
+++ b/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/MailingList.java
@@ -30,8 +30,11 @@ import java.util.List;
  */
 @XmlRootElement(name = "mailingList")
 public class MailingList
-    implements Serializable
+    implements Serializable, Comparable<MailingList>
 {
+
+    private Integer index;
+
     /**
      * The primary archive URL for this mailing list.
      */
@@ -134,4 +137,17 @@ public class MailingList
             ", unsubscribeAddress='" + unsubscribeAddress + '\'' +
             '}';
     }
+
+    public Integer getIndex() {
+        return index;
+    }
+
+    public void setIndex(Integer index) {
+        this.index = index;
+    }
+
+    @Override
+    public int compareTo(MailingList o) {
+        return this.index.compareTo(o.getIndex());
+    }
 }
diff --git a/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java b/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java
index 48d8cb9..65b6b3e 100644
--- a/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java
+++ b/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java
@@ -419,7 +419,7 @@ public abstract class AbstractMetadataRepositoryTest
             Dependency d = new Dependency( );
             d.setArtifactId( "artifactId" );
             d.setClassifier( "classifier" );
-            d.setGroupId( "groupId" );
+            d.setNamespace( "groupId" );
             d.setScope( "scope" );
             d.setSystemPath( "system path" );
             d.setType( "type" );
@@ -471,7 +471,7 @@ public abstract class AbstractMetadataRepositoryTest
             d = metadata.getDependencies( ).get( 0 );
             assertEquals( "artifactId", d.getArtifactId( ) );
             assertEquals( "classifier", d.getClassifier( ) );
-            assertEquals( "groupId", d.getGroupId( ) );
+            assertEquals( "groupId", d.getNamespace( ) );
             assertEquals( "scope", d.getScope( ) );
             assertEquals( "system path", d.getSystemPath( ) );
             assertEquals( "type", d.getType( ) );
@@ -2080,7 +2080,7 @@ public abstract class AbstractMetadataRepositoryTest
             Dependency d = new Dependency( );
             d.setArtifactId( "artifactId" );
             d.setClassifier( "classifier" );
-            d.setGroupId( "groupId" );
+            d.setNamespace( "groupId" );
             d.setScope( "scope" );
             d.setSystemPath( "system path" );
             d.setType( "type" );
@@ -2091,7 +2091,7 @@ public abstract class AbstractMetadataRepositoryTest
             d = new Dependency( );
             d.setArtifactId( "artifactId1" );
             d.setClassifier( "classifier" );
-            d.setGroupId( "groupId" );
+            d.setNamespace( "groupId" );
             d.setScope( "scope" );
             d.setSystemPath( "system path" );
             d.setType( "type" );
@@ -2110,7 +2110,7 @@ public abstract class AbstractMetadataRepositoryTest
             tryAssert( ( ) -> {
 
                 Collection<ProjectVersionReference> references =
-                    getRepository( ).getProjectReferences( session, TEST_REPO_ID, dd.getGroupId( ), dd.getArtifactId( ), dd.getVersion( ) );
+                    getRepository( ).getProjectReferences( session, TEST_REPO_ID, dd.getNamespace( ), dd.getArtifactId( ), dd.getVersion( ) );
                     log.info( "references: {}", references );
                 assertThat( references ).isNotNull( ).hasSize( 1 ).contains(
                     new ProjectVersionReference( ProjectVersionReference.ReferenceType.DEPENDENCY, TEST_PROJECT, TEST_NAMESPACE,
diff --git a/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java b/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java
index 7a020ef..84343b7 100644
--- a/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java
+++ b/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java
@@ -1317,7 +1317,7 @@ public class CassandraMetadataRepository
 
             addInsertion( dependencyMutator, keyDependency, cfDependency, ARTIFACT_ID.toString(), dependency.getArtifactId() );
 
-            addInsertion( dependencyMutator, keyDependency, cfDependency, GROUP_ID.toString(), dependency.getGroupId() );
+            addInsertion( dependencyMutator, keyDependency, cfDependency, GROUP_ID.toString(), dependency.getNamespace() );
 
             addInsertion( dependencyMutator, keyDependency, cfDependency, VERSION.toString(), dependency.getVersion() );
 
@@ -1371,7 +1371,7 @@ public class CassandraMetadataRepository
 
             dependency.setArtifactId( columnFamilyResult.getString( ARTIFACT_ID.toString() ) );
 
-            dependency.setGroupId( columnFamilyResult.getString( GROUP_ID.toString() ) );
+            dependency.setNamespace( columnFamilyResult.getString( GROUP_ID.toString() ) );
 
             dependency.setVersion( columnFamilyResult.getString( VERSION.toString() ) );
 
diff --git a/archiva-modules/plugins/metadata-store-file/src/main/java/org/apache/archiva/metadata/repository/file/FileMetadataRepository.java b/archiva-modules/plugins/metadata-store-file/src/main/java/org/apache/archiva/metadata/repository/file/FileMetadataRepository.java
index a5e63a2..2ff7ba3 100644
--- a/archiva-modules/plugins/metadata-store-file/src/main/java/org/apache/archiva/metadata/repository/file/FileMetadataRepository.java
+++ b/archiva-modules/plugins/metadata-store-file/src/main/java/org/apache/archiva/metadata/repository/file/FileMetadataRepository.java
@@ -218,12 +218,12 @@ public class FileMetadataRepository
                 setProperty(properties, "dependency." + i + ".scope", dependency.getScope());
                 setProperty(properties, "dependency." + i + ".systemPath", dependency.getSystemPath());
                 setProperty(properties, "dependency." + i + ".artifactId", dependency.getArtifactId());
-                setProperty(properties, "dependency." + i + ".groupId", dependency.getGroupId());
+                setProperty(properties, "dependency." + i + ".groupId", dependency.getNamespace());
                 setProperty(properties, "dependency." + i + ".version", dependency.getVersion());
                 setProperty(properties, "dependency." + i + ".type", dependency.getType());
                 setProperty(properties, "dependency." + i + ".optional", String.valueOf(dependency.isOptional()));
 
-                updateProjectReference(repoId, dependency.getGroupId(), dependency.getArtifactId(),
+                updateProjectReference(repoId, dependency.getNamespace(), dependency.getArtifactId(),
                         dependency.getVersion(), reference);
 
                 i++;
@@ -948,7 +948,7 @@ public class FileMetadataRepository
                     if (dependencyArtifactId != null) {
                         Dependency dependency = new Dependency();
                         dependency.setArtifactId(dependencyArtifactId);
-                        dependency.setGroupId(properties.getProperty("dependency." + i + ".groupId"));
+                        dependency.setNamespace(properties.getProperty("dependency." + i + ".groupId"));
                         dependency.setClassifier(properties.getProperty("dependency." + i + ".classifier"));
                         dependency.setOptional(
                                 Boolean.valueOf(properties.getProperty("dependency." + i + ".optional")));
diff --git a/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrConstants.java b/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrConstants.java
index 330c060..a52f9c1 100644
--- a/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrConstants.java
+++ b/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrConstants.java
@@ -44,7 +44,12 @@ public interface JcrConstants
     String MIXIN_META_ORGANIZATION = "archiva:meta_organization";
     String MIXIN_META_LICENSE = "archiva:meta_license";
     String MIXIN_META_MAILINGLIST = "archiva:meta_mailinglist";
+    String MAILINGLIST_NODE_TYPE = "archiva:mailinglist";
+    String MAILINGLISTS_FOLDER_TYPE = "archiva:mailinglists";
+    String LICENSES_FOLDER_TYPE = "archiva:licenses";
+    String LICENSE_NODE_TYPE = "archiva:license";
     String DEPENDENCY_NODE_TYPE = "archiva:dependency";
+    String DEPENDENCIES_FOLDER_TYPE = "archiva:dependencies";
     String CHECKSUM_NODE_TYPE = "archiva:checksum";
     String CHECKSUMS_FOLDER_TYPE = "archiva:checksums";
     String FACETS_FOLDER_TYPE = "archiva:facets";
diff --git a/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java b/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java
index 15d3013..9260c54 100644
--- a/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java
+++ b/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java
@@ -24,13 +24,7 @@ import org.apache.archiva.checksum.ChecksumAlgorithm;
 import org.apache.archiva.metadata.QueryParameter;
 import org.apache.archiva.metadata.model.*;
 import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet;
-import org.apache.archiva.metadata.repository.AbstractMetadataRepository;
-import org.apache.archiva.metadata.repository.MetadataRepository;
-import org.apache.archiva.metadata.repository.MetadataRepositoryException;
-import org.apache.archiva.metadata.repository.MetadataResolutionException;
-import org.apache.archiva.metadata.repository.MetadataService;
-import org.apache.archiva.metadata.repository.MetadataSessionException;
-import org.apache.archiva.metadata.repository.RepositorySession;
+import org.apache.archiva.metadata.repository.*;
 import org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics;
 import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsProvider;
 import org.apache.commons.lang.StringUtils;
@@ -42,23 +36,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.annotation.ParametersAreNonnullByDefault;
-import javax.jcr.NamespaceRegistry;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.PathNotFoundException;
-import javax.jcr.Property;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-import javax.jcr.Value;
-import javax.jcr.ValueFactory;
-import javax.jcr.Workspace;
-import javax.jcr.query.Query;
-import javax.jcr.query.QueryManager;
-import javax.jcr.query.QueryResult;
-import javax.jcr.query.Row;
-import javax.jcr.query.RowIterator;
+import javax.jcr.*;
+import javax.jcr.query.*;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.Reader;
@@ -67,6 +46,7 @@ import java.util.*;
 import java.util.Map.Entry;
 import java.util.function.Consumer;
 import java.util.function.Function;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 
@@ -79,43 +59,40 @@ import static org.apache.archiva.metadata.repository.jcr.JcrConstants.*;
  */
 @ParametersAreNonnullByDefault
 public class JcrMetadataRepository
-    extends AbstractMetadataRepository implements MetadataRepository, RepositoryStatisticsProvider
-{
+        extends AbstractMetadataRepository implements MetadataRepository, RepositoryStatisticsProvider {
 
 
     private static final String QUERY_ARTIFACT_1 = "SELECT * FROM [" + ARTIFACT_NODE_TYPE + "] AS artifact WHERE ISDESCENDANTNODE(artifact,'/";
 
     static final String QUERY_ARTIFACTS_BY_PROJECT_VERSION_1 = "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE + "] AS projectVersion INNER JOIN [" + ARTIFACT_NODE_TYPE
-        + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) INNER JOIN [" + FACET_NODE_TYPE
-        + "] AS facet ON ISCHILDNODE(facet, projectVersion) WHERE ([facet].[";
-    static final String QUERY_ARTIFACTS_BY_PROJECT_VERSION_2= "] = $value)";
+            + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) INNER JOIN [" + FACET_NODE_TYPE
+            + "] AS facet ON ISCHILDNODE(facet, projectVersion) WHERE ([facet].[";
+    static final String QUERY_ARTIFACTS_BY_PROJECT_VERSION_2 = "] = $value)";
 
     static final String QUERY_ARTIFACTS_BY_METADATA_1 = "SELECT * FROM [" + ARTIFACT_NODE_TYPE + "] AS artifact INNER JOIN [" + FACET_NODE_TYPE
-        + "] AS facet ON ISCHILDNODE(facet, artifact) WHERE ([facet].[";
+            + "] AS facet ON ISCHILDNODE(facet, artifact) WHERE ([facet].[";
     static final String QUERY_ARTIFACTS_BY_METADATA_2 = "] = $value)";
 
     static final String QUERY_ARTIFACTS_BY_PROPERTY_1 = "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE + "] AS projectVersion INNER JOIN [" + ARTIFACT_NODE_TYPE
-           + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) WHERE ([projectVersion].[";
+            + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) WHERE ([projectVersion].[";
     static final String QUERY_ARTIFACTS_BY_PROPERTY_2 = "] = $value)";
 
 
     private static final String QUERY_ARTIFACT_2 = "')";
 
-    private Logger log = LoggerFactory.getLogger( JcrMetadataRepository.class );
+    private Logger log = LoggerFactory.getLogger(JcrMetadataRepository.class);
 
     private Repository repository;
 
-    public JcrMetadataRepository( MetadataService metadataService, Repository repository )
-        throws RepositoryException
-    {
-        super( metadataService );
+    public JcrMetadataRepository(MetadataService metadataService, Repository repository)
+            throws RepositoryException {
+        super(metadataService);
         this.repository = repository;
     }
 
 
-    public static void initializeNodeTypes( Session session )
-        throws RepositoryException
-    {
+    public static void initializeNodeTypes(Session session)
+            throws RepositoryException {
 
         // TODO: consider using namespaces for facets instead of the current approach:
         // (if used, check if actually called by normal injection)
@@ -126,224 +103,221 @@ public class JcrMetadataRepository
         Workspace workspace = session.getWorkspace();
         NamespaceRegistry registry = workspace.getNamespaceRegistry();
 
-        if ( !Arrays.asList( registry.getPrefixes() ).contains( "archiva" ) )
-        {
-            registry.registerNamespace( "archiva", "http://archiva.apache.org/jcr/" );
+        if (!Arrays.asList(registry.getPrefixes()).contains("archiva")) {
+            registry.registerNamespace("archiva", "http://archiva.apache.org/jcr/");
         }
 
-        try(
-            Reader cndReader = new InputStreamReader(
-                Thread.currentThread( ).getContextClassLoader( ).getResourceAsStream( "org/apache/archiva/metadata/repository/jcr/jcr-schema.cnd" ) ))
-        {
-            CndImporter.registerNodeTypes( cndReader, session );
-        }
-        catch ( ParseException e )
-        {
-            e.printStackTrace( );
-        }
-        catch ( IOException e )
-        {
-            e.printStackTrace( );
+        try (
+                Reader cndReader = new InputStreamReader(
+                        Thread.currentThread().getContextClassLoader().getResourceAsStream("org/apache/archiva/metadata/repository/jcr/jcr-schema.cnd"))) {
+            CndImporter.registerNodeTypes(cndReader, session);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
         }
 
     }
 
     private Session getSession(RepositorySession repositorySession) throws MetadataRepositoryException {
-        if (repositorySession instanceof JcrRepositorySession ) {
-            return ( (JcrRepositorySession) repositorySession ).getJcrSession();
+        if (repositorySession instanceof JcrRepositorySession) {
+            return ((JcrRepositorySession) repositorySession).getJcrSession();
         } else {
-            throw new MetadataRepositoryException( "The given session object is not a JcrSession instance: " + repositorySession.getClass( ).getName( ) );
+            throw new MetadataRepositoryException("The given session object is not a JcrSession instance: " + repositorySession.getClass().getName());
         }
     }
 
     @Override
-    public void updateProject( RepositorySession session, String repositoryId, ProjectMetadata project )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        updateProject( jcrSession, repositoryId, project.getNamespace(), project.getId() );
+    public void updateProject(RepositorySession session, String repositoryId, ProjectMetadata project)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        updateProject(jcrSession, repositoryId, project.getNamespace(), project.getId());
     }
 
-    private void updateProject( Session jcrSession, String repositoryId, String namespace, String projectId )
-        throws MetadataRepositoryException
-    {
-        updateNamespace( jcrSession , repositoryId, namespace );
+    private void updateProject(Session jcrSession, String repositoryId, String namespace, String projectId)
+            throws MetadataRepositoryException {
+        updateNamespace(jcrSession, repositoryId, namespace);
 
-        try
-        {
-            getOrAddProjectNode( jcrSession, repositoryId, namespace, projectId );
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        try {
+            getOrAddProjectNode(jcrSession, repositoryId, namespace, projectId);
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
     @Override
-    public void updateArtifact( RepositorySession session, String repositoryId, String namespace, String projectId, String projectVersion,
-                                ArtifactMetadata artifactMeta )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        updateNamespace( session, repositoryId, namespace );
-
-        try
-        {
+    public void updateArtifact(RepositorySession session, String repositoryId, String namespace, String projectId, String projectVersion,
+                               ArtifactMetadata artifactMeta)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        updateNamespace(session, repositoryId, namespace);
+
+        try {
             Node node =
-                getOrAddArtifactNode( jcrSession, repositoryId, namespace, projectId, projectVersion, artifactMeta.getId() );
+                    getOrAddArtifactNode(jcrSession, repositoryId, namespace, projectId, projectVersion, artifactMeta.getId());
 
-            node.setProperty( "id", artifactMeta.getId( ) );
+            node.setProperty("id", artifactMeta.getId());
             Calendar cal = GregorianCalendar.from(artifactMeta.getFileLastModified());
-            node.setProperty( JCR_LAST_MODIFIED, cal );
+            node.setProperty(JCR_LAST_MODIFIED, cal);
 
             cal = GregorianCalendar.from(artifactMeta.getWhenGathered());
-            node.setProperty( "whenGathered", cal );
+            node.setProperty("whenGathered", cal);
 
-            node.setProperty( "size", artifactMeta.getSize() );
+            node.setProperty("size", artifactMeta.getSize());
 
-            int idx=0;
-            Node cslistNode = getOrAddNodeByPath( node, "checksums", CHECKSUMS_FOLDER_TYPE, true );
+            int idx = 0;
+            Node cslistNode = getOrAddNodeByPath(node, "checksums", CHECKSUMS_FOLDER_TYPE, true);
             NodeIterator nit = cslistNode.getNodes("*");
             while (nit.hasNext()) {
                 Node csNode = nit.nextNode();
-                if (csNode.isNodeType( CHECKSUM_NODE_TYPE )) {
+                if (csNode.isNodeType(CHECKSUM_NODE_TYPE)) {
                     csNode.remove();
                 }
             }
-            for ( Map.Entry<ChecksumAlgorithm, String> entry : artifactMeta.getChecksums().entrySet()) {
-                String type = entry.getKey( ).name( );
-                Node csNode = cslistNode.addNode( type , CHECKSUM_NODE_TYPE);
-                csNode.setProperty( "type", type );
-                csNode.setProperty( "value", entry.getValue( ) );
+            for (Map.Entry<ChecksumAlgorithm, String> entry : artifactMeta.getChecksums().entrySet()) {
+                String type = entry.getKey().name();
+                Node csNode = cslistNode.addNode(type, CHECKSUM_NODE_TYPE);
+                csNode.setProperty("type", type);
+                csNode.setProperty("value", entry.getValue());
             }
 
-            node.setProperty( "version", artifactMeta.getVersion() );
+            node.setProperty("version", artifactMeta.getVersion());
 
             // iterate over available facets to update/add/remove from the artifactMetadata
-            for ( String facetId : metadataService.getSupportedFacets() )
-            {
-                MetadataFacet metadataFacet = artifactMeta.getFacet( facetId );
-                if ( metadataFacet == null )
-                {
+            for (String facetId : metadataService.getSupportedFacets()) {
+                MetadataFacet metadataFacet = artifactMeta.getFacet(facetId);
+                if (metadataFacet == null) {
                     continue;
                 }
-                if ( node.hasNode( facetId ) )
-                {
-                    node.getNode( facetId ).remove();
+                if (node.hasNode(facetId)) {
+                    node.getNode(facetId).remove();
                 }
-                if ( metadataFacet != null )
-                {
+                if (metadataFacet != null) {
                     // recreate, to ensure properties are removed
-                    Node n = node.addNode( facetId, FACET_NODE_TYPE);
-                    n.setProperty( "facetId", facetId );
+                    Node n = node.addNode(facetId, FACET_NODE_TYPE);
+                    n.setProperty("facetId", facetId);
 
-                    for ( Map.Entry<String, String> entry : metadataFacet.toProperties().entrySet() )
-                    {
-                        n.setProperty( entry.getKey(), entry.getValue() );
+                    for (Map.Entry<String, String> entry : metadataFacet.toProperties().entrySet()) {
+                        n.setProperty(entry.getKey(), entry.getValue());
                     }
                 }
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
     @Override
-    public void updateProjectVersion( RepositorySession session, String repositoryId, String namespace, String projectId,
-                                      ProjectVersionMetadata versionMetadata )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        updateProject( jcrSession, repositoryId, namespace, projectId );
-
-        try
-        {
+    public void updateProjectVersion(RepositorySession session, String repositoryId, String namespace, String projectId,
+                                     ProjectVersionMetadata versionMetadata)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        updateProject(jcrSession, repositoryId, namespace, projectId);
+
+        try {
             Node versionNode =
-                getOrAddProjectVersionNode( jcrSession, repositoryId, namespace, projectId, versionMetadata.getId() );
-            versionNode.setProperty( "id", versionMetadata.getId( ) );
-            versionNode.setProperty( "name", StringUtils.isEmpty( versionMetadata.getName() ) ? "" : versionMetadata.getName() );
-            versionNode.setProperty( "description", StringUtils.isEmpty( versionMetadata.getDescription() ) ? "" : versionMetadata.getDescription() );
-            versionNode.setProperty( "url", versionMetadata.getUrl() );
-            versionNode.setProperty( "incomplete", versionMetadata.isIncomplete() );
+                    getOrAddProjectVersionNode(jcrSession, repositoryId, namespace, projectId, versionMetadata.getId());
+            versionNode.setProperty("id", versionMetadata.getId());
+            versionNode.setProperty("name", StringUtils.isEmpty(versionMetadata.getName()) ? "" : versionMetadata.getName());
+            versionNode.setProperty("description", StringUtils.isEmpty(versionMetadata.getDescription()) ? "" : versionMetadata.getDescription());
+            versionNode.setProperty("url", versionMetadata.getUrl());
+            versionNode.setProperty("incomplete", versionMetadata.isIncomplete());
 
             // FIXME: decide how to treat these in the content repo
-            if ( versionMetadata.getScm() != null )
-            {
-                versionNode.setProperty( "scm.connection", versionMetadata.getScm().getConnection() );
-                versionNode.setProperty( "scm.developerConnection", versionMetadata.getScm().getDeveloperConnection() );
-                versionNode.setProperty( "scm.url", versionMetadata.getScm().getUrl() );
-            }
-            if ( versionMetadata.getCiManagement() != null )
-            {
-                versionNode.setProperty( "ci.system", versionMetadata.getCiManagement().getSystem() );
-                versionNode.setProperty( "ci.url", versionMetadata.getCiManagement().getUrl() );
-            }
-            if ( versionMetadata.getIssueManagement() != null )
-            {
-                versionNode.setProperty( "issue.system", versionMetadata.getIssueManagement().getSystem() );
-                versionNode.setProperty( "issue.url", versionMetadata.getIssueManagement().getUrl() );
-            }
-            if ( versionMetadata.getOrganization() != null )
-            {
-                versionNode.setProperty( "org.name", versionMetadata.getOrganization().getName() );
-                versionNode.setProperty( "org.url", versionMetadata.getOrganization().getUrl() );
+            if (versionMetadata.getScm() != null) {
+                versionNode.setProperty("scm.connection", versionMetadata.getScm().getConnection());
+                versionNode.setProperty("scm.developerConnection", versionMetadata.getScm().getDeveloperConnection());
+                versionNode.setProperty("scm.url", versionMetadata.getScm().getUrl());
+            }
+            if (versionMetadata.getCiManagement() != null) {
+                versionNode.setProperty("ci.system", versionMetadata.getCiManagement().getSystem());
+                versionNode.setProperty("ci.url", versionMetadata.getCiManagement().getUrl());
+            }
+            if (versionMetadata.getIssueManagement() != null) {
+                versionNode.setProperty("issue.system", versionMetadata.getIssueManagement().getSystem());
+                versionNode.setProperty("issue.url", versionMetadata.getIssueManagement().getUrl());
+            }
+            if (versionMetadata.getOrganization() != null) {
+                versionNode.setProperty("org.name", versionMetadata.getOrganization().getName());
+                versionNode.setProperty("org.url", versionMetadata.getOrganization().getUrl());
             }
             int i = 0;
-            for ( License license : versionMetadata.getLicenses() )
-            {
-                versionNode.setProperty( "license." + i + ".name", license.getName() );
-                versionNode.setProperty( "license." + i + ".url", license.getUrl() );
+            Node licensesNode = JcrUtils.getOrAddNode(versionNode, "licenses", LICENSES_FOLDER_TYPE);
+            Set<String> licNames = new HashSet<>();
+            for (License license : versionMetadata.getLicenses()) {
+                Node licNode = JcrUtils.getOrAddNode(licensesNode, license.getName(), LICENSE_NODE_TYPE);
+                licNode.setProperty("index", i);
+                licNode.setProperty("name", license.getName());
+                licNode.setProperty("url", license.getUrl());
+                licNames.add(license.getName());
                 i++;
             }
+            NodeIterator nodeIterator = licensesNode.getNodes();
+            while (nodeIterator.hasNext()) {
+                Node n = nodeIterator.nextNode();
+                if (!licNames.contains(n.getName())) {
+                    n.remove();
+                }
+            }
             i = 0;
-            for ( MailingList mailingList : versionMetadata.getMailingLists() )
-            {
-                versionNode.setProperty( "mailingList." + i + ".archive", mailingList.getMainArchiveUrl() );
-                versionNode.setProperty( "mailingList." + i + ".name", mailingList.getName() );
-                versionNode.setProperty( "mailingList." + i + ".post", mailingList.getPostAddress() );
-                versionNode.setProperty( "mailingList." + i + ".unsubscribe", mailingList.getUnsubscribeAddress() );
-                versionNode.setProperty( "mailingList." + i + ".subscribe", mailingList.getSubscribeAddress() );
-                versionNode.setProperty( "mailingList." + i + ".otherArchives",
-                                         join( mailingList.getOtherArchives() ) );
+            Node mailinglistsListNode = JcrUtils.getOrAddNode(versionNode, "mailinglists", MAILINGLISTS_FOLDER_TYPE);
+            Set<String> listNames = new HashSet<>();
+            for (MailingList mailingList : versionMetadata.getMailingLists()) {
+                final String name = mailingList.getName();
+                Node mailNode = JcrUtils.getOrAddNode(mailinglistsListNode, mailingList.getName(), MAILINGLIST_NODE_TYPE);
+                mailNode.setProperty("index", i);
+                mailNode.setProperty("archive", mailingList.getMainArchiveUrl());
+                mailNode.setProperty("name", mailingList.getName());
+                mailNode.setProperty("post", mailingList.getPostAddress());
+                mailNode.setProperty("unsubscribe", mailingList.getUnsubscribeAddress());
+                mailNode.setProperty("subscribe", mailingList.getSubscribeAddress());
+                mailNode.setProperty("otherArchives",
+                        join(mailingList.getOtherArchives()));
                 i++;
+                listNames.add(name);
             }
+            nodeIterator = mailinglistsListNode.getNodes();
+            while (nodeIterator.hasNext()) {
+                Node n = nodeIterator.nextNode();
+                if (!listNames.contains(n.getName())) {
+                    n.remove();
+                }
+            }
+            if (!versionMetadata.getDependencies().isEmpty()) {
+                Node dependenciesNode = JcrUtils.getOrAddNode(versionNode, "dependencies", DEPENDENCIES_FOLDER_TYPE);
 
-            if ( !versionMetadata.getDependencies().isEmpty() )
-            {
-                Node dependenciesNode = JcrUtils.getOrAddNode( versionNode, "dependencies" );
-
-                for ( Dependency dependency : versionMetadata.getDependencies() )
-                {
+                for (Dependency dependency : versionMetadata.getDependencies()) {
                     // Note that we deliberately don't alter the namespace path - not enough dependencies for
                     // number of nodes at a given depth to be an issue. Similarly, we don't add subnodes for each
                     // component of the ID as that creates extra depth and causes a great cost in space and memory
 
-                    // FIXME: change group ID to namespace
                     // FIXME: change to artifact's ID - this is constructed by the Maven 2 format for now.
                     //        This won't support types where the extension doesn't match the type.
                     //        (see also Maven2RepositoryStorage#readProjectVersionMetadata construction of POM)
                     String id =
-                        dependency.getGroupId() + ";" + dependency.getArtifactId() + "-" + dependency.getVersion();
-                    if ( dependency.getClassifier() != null )
-                    {
+                            dependency.getNamespace() + ";" + dependency.getArtifactId() + "-" + dependency.getVersion();
+                    if (dependency.getClassifier() != null) {
                         id += "-" + dependency.getClassifier();
                     }
                     id += "." + dependency.getType();
 
-                    Node n = JcrUtils.getOrAddNode( dependenciesNode, id, DEPENDENCY_NODE_TYPE );
-                    n.setProperty( "id", id );
-
-                    // FIXME: remove temp code just to make it keep working
-                    n.setProperty( "groupId", dependency.getGroupId() );
-                    n.setProperty( "artifactId", dependency.getArtifactId() );
-                    n.setProperty( "version", dependency.getVersion() );
-                    n.setProperty( "type", dependency.getType() );
-                    n.setProperty( "classifier", dependency.getClassifier() );
-                    n.setProperty( "scope", dependency.getScope() );
-                    n.setProperty( "systemPath", dependency.getSystemPath() );
-                    n.setProperty( "optional", dependency.isOptional() );
+                    Node n = JcrUtils.getOrAddNode(dependenciesNode, id, DEPENDENCY_NODE_TYPE);
+                    n.setProperty("id", id);
+
+                    n.setProperty("namespace", dependency.getNamespace());
+                    n.setProperty("artifactId", dependency.getArtifactId());
+                    n.setProperty("version", dependency.getVersion());
+                    n.setProperty("type", dependency.getType());
+                    n.setProperty("classifier", dependency.getClassifier());
+                    n.setProperty("scope", dependency.getScope());
+                    n.setProperty("systemPath", dependency.getSystemPath());
+                    n.setProperty("optional", dependency.isOptional());
+                    n.setProperty("projectId", dependency.getProjectId());
+                    Node refNode = findArtifactNode(jcrSession, dependency.getNamespace(),
+                            dependency.getProjectId(), dependency.getVersion(), dependency.getArtifactId());
+                    if (refNode!=null) {
+                        n.setProperty("link", refNode.getPath());
+                    }
 
                     // node has no native content at this time, just facets
                     // no need to list a type as it's implied by the path. Parents are Maven specific.
@@ -360,150 +334,114 @@ public class JcrMetadataRepository
                 }
             }
 
-            for ( MetadataFacet facet : versionMetadata.getFacetList() )
-            {
+            for (MetadataFacet facet : versionMetadata.getFacetList()) {
                 // recreate, to ensure properties are removed
-                if ( versionNode.hasNode( facet.getFacetId() ) )
-                {
-                    versionNode.getNode( facet.getFacetId() ).remove();
+                if (versionNode.hasNode(facet.getFacetId())) {
+                    versionNode.getNode(facet.getFacetId()).remove();
                 }
-                Node n = versionNode.addNode( facet.getFacetId(), FACET_NODE_TYPE );
+                Node n = versionNode.addNode(facet.getFacetId(), FACET_NODE_TYPE);
 
-                for ( Map.Entry<String, String> entry : facet.toProperties().entrySet() )
-                {
-                    n.setProperty( entry.getKey(), entry.getValue() );
+                for (Map.Entry<String, String> entry : facet.toProperties().entrySet()) {
+                    n.setProperty(entry.getKey(), entry.getValue());
                 }
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
-    private void updateNamespace(Session jcrSession, String repositoryId, String namespace) throws MetadataRepositoryException
-    {
-        try
-        {
-            Node node = getOrAddNamespaceNode( jcrSession, repositoryId, namespace );
-            node.setProperty( "id", namespace );
-            node.setProperty( "namespace", namespace );
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+    private void updateNamespace(Session jcrSession, String repositoryId, String namespace) throws MetadataRepositoryException {
+        try {
+            Node node = getOrAddNamespaceNode(jcrSession, repositoryId, namespace);
+            node.setProperty("id", namespace);
+            node.setProperty("namespace", namespace);
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
     @Override
-    public void updateNamespace( RepositorySession session, String repositoryId, String namespace )
-        throws MetadataRepositoryException
-    {
-        updateNamespace( getSession(session), repositoryId, namespace );
+    public void updateNamespace(RepositorySession session, String repositoryId, String namespace)
+            throws MetadataRepositoryException {
+        updateNamespace(getSession(session), repositoryId, namespace);
     }
 
     @Override
-    public void removeProject( RepositorySession session, String repositoryId, String namespace, String projectId )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        try
-        {
+    public void removeProject(RepositorySession session, String repositoryId, String namespace, String projectId)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        try {
             Node root = jcrSession.getRootNode();
-            String namespacePath = getNamespacePath( repositoryId, namespace );
+            String namespacePath = getNamespacePath(repositoryId, namespace);
 
-            if ( root.hasNode( namespacePath ) )
-            {
-                Iterator<Node> nodeIterator = JcrUtils.getChildNodes( root.getNode( namespacePath ) ).iterator();
-                while ( nodeIterator.hasNext() )
-                {
+            if (root.hasNode(namespacePath)) {
+                Iterator<Node> nodeIterator = JcrUtils.getChildNodes(root.getNode(namespacePath)).iterator();
+                while (nodeIterator.hasNext()) {
                     Node node = nodeIterator.next();
-                    if ( node.isNodeType( org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_NODE_TYPE ) && projectId.equals( node.getName() ) )
-                    {
+                    if (node.isNodeType(org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_NODE_TYPE) && projectId.equals(node.getName())) {
                         node.remove();
                     }
                 }
 
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
 
     }
 
 
     @Override
-    public boolean hasMetadataFacet( RepositorySession session, String repositoryId, String facetId )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        try
-        {
-            Node node = jcrSession.getRootNode().getNode( getFacetPath( repositoryId, facetId ) );
+    public boolean hasMetadataFacet(RepositorySession session, String repositoryId, String facetId)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        try {
+            Node node = jcrSession.getRootNode().getNode(getFacetPath(repositoryId, facetId));
             return node.getNodes().hasNext();
-        }
-        catch ( PathNotFoundException e )
-        {
+        } catch (PathNotFoundException e) {
             // ignored - the facet doesn't exist, so return false
             return false;
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
     @Override
-    public List<String> getMetadataFacets( RepositorySession session, String repositoryId, String facetId )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
+    public List<String> getMetadataFacets(RepositorySession session, String repositoryId, String facetId)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
         List<String> facets = new ArrayList<>();
 
-        try
-        {
+        try {
             // no need to construct node-by-node here, as we'll find in the next instance, the facet names have / and
             // are paths themselves
-            Node node = jcrSession.getRootNode().getNode( getFacetPath( repositoryId, facetId ) );
+            Node node = jcrSession.getRootNode().getNode(getFacetPath(repositoryId, facetId));
 
             // TODO: this is a bit awkward. Might be better to review the purpose of this function - why is the list of
             //   paths helpful?
-            recurse( facets, "", node );
-        }
-        catch ( PathNotFoundException e )
-        {
+            recurse(facets, "", node);
+        } catch (PathNotFoundException e) {
             // ignored - the facet doesn't exist, so return the empty list
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
         return facets;
     }
 
-    private <T> Spliterator<T> createResultSpliterator(QueryResult result, Function<Row, T> converter) throws MetadataRepositoryException
-    {
+    private <T> Spliterator<T> createResultSpliterator(QueryResult result, Function<Row, T> converter) throws MetadataRepositoryException {
         final RowIterator rowIterator;
-        try
-        {
+        try {
             rowIterator = result.getRows();
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage( ), e );
-        }
-        return new Spliterator<T>( )
-        {
+        return new Spliterator<T>() {
             @Override
-            public boolean tryAdvance( Consumer<? super T> action )
-            {
+            public boolean tryAdvance(Consumer<? super T> action) {
                 while (rowIterator.hasNext()) {
-                    T item = converter.apply( rowIterator.nextRow() );
-                    if (item!=null)
-                    {
-                        action.accept( item );
+                    T item = converter.apply(rowIterator.nextRow());
+                    if (item != null) {
+                        action.accept(item);
                         return true;
                     }
                 }
@@ -511,27 +449,24 @@ public class JcrMetadataRepository
             }
 
             @Override
-            public Spliterator<T> trySplit( )
-            {
+            public Spliterator<T> trySplit() {
                 return null;
             }
 
             @Override
-            public long estimateSize( )
-            {
+            public long estimateSize() {
                 return 0;
             }
 
             @Override
-            public int characteristics( )
-            {
-                return ORDERED+NONNULL;
+            public int characteristics() {
+                return ORDERED + NONNULL;
             }
         };
     }
 
     private StringBuilder appendQueryParams(StringBuilder query, String selector, String defaultProperty, QueryParameter queryParameter) {
-        if (queryParameter.getSortFields().size()==0) {
+        if (queryParameter.getSortFields().size() == 0) {
             query.append(" ORDER BY [").append(selector).append("].[").append(defaultProperty).append("]");
             if (queryParameter.isAscending()) {
                 query.append(" ASC");
@@ -552,94 +487,77 @@ public class JcrMetadataRepository
         return query;
     }
 
-    private <T extends MetadataFacet> Function<Row, Optional<T>> getFacetFromRowFunc( MetadataFacetFactory<T> factory, String repositoryId ) {
+    private <T extends MetadataFacet> Function<Row, Optional<T>> getFacetFromRowFunc(MetadataFacetFactory<T> factory, String repositoryId) {
         return (Row row) -> {
-            try
-            {
-                Node node = row.getNode( "facet" );
-                if (node.hasProperty( "archiva:name" ))
-                {
-                    String facetName = node.getProperty( "archiva:name" ).getString( );
-                    return Optional.ofNullable( createFacetFromNode( factory, node, repositoryId, facetName ) );
+            try {
+                Node node = row.getNode("facet");
+                if (node.hasProperty("archiva:name")) {
+                    String facetName = node.getProperty("archiva:name").getString();
+                    return Optional.ofNullable(createFacetFromNode(factory, node, repositoryId, facetName));
                 } else {
-                    return Optional.empty( );
+                    return Optional.empty();
                 }
-            }
-            catch ( RepositoryException e )
-            {
-                log.error( "Exception encountered {}", e.getMessage( ) );
+            } catch (RepositoryException e) {
+                log.error("Exception encountered {}", e.getMessage());
                 return Optional.empty();
             }
         };
     }
 
     @Override
-    public <T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter) throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        final MetadataFacetFactory<T> factory = metadataService.getFactory( facetClazz );
-        final String facetId = factory.getFacetId( );
-        final String facetPath = '/'+getFacetPath( repositoryId, facetId );
+    public <T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter) throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        final MetadataFacetFactory<T> factory = metadataService.getFactory(facetClazz);
+        final String facetId = factory.getFacetId();
+        final String facetPath = '/' + getFacetPath(repositoryId, facetId);
         StringBuilder query = new StringBuilder("SELECT * FROM [");
         query.append(FACET_NODE_TYPE).append("] AS facet WHERE ISDESCENDANTNODE(facet, [")
                 .append(facetPath).append("]) AND [facet].[archiva:name] IS NOT NULL");
         appendQueryParams(query, "facet", "archiva:name", queryParameter);
         String q = query.toString();
-        Map<String, String> params = new HashMap<>( );
-        QueryResult result = runNativeJcrQuery( jcrSession, q, params, queryParameter.getOffset(), queryParameter.getLimit());
-        final Function<Row, Optional<T>> rowFunc = getFacetFromRowFunc( factory, repositoryId );
-        return StreamSupport.stream( createResultSpliterator( result, rowFunc), false ).filter( Optional::isPresent ).map(Optional::get);
+        Map<String, String> params = new HashMap<>();
+        QueryResult result = runNativeJcrQuery(jcrSession, q, params, queryParameter.getOffset(), queryParameter.getLimit());
+        final Function<Row, Optional<T>> rowFunc = getFacetFromRowFunc(factory, repositoryId);
+        return StreamSupport.stream(createResultSpliterator(result, rowFunc), false).filter(Optional::isPresent).map(Optional::get);
 
     }
 
-    private void recurse( List<String> facets, String prefix, Node node )
-        throws RepositoryException
-    {
-        for ( Node n : JcrUtils.getChildNodes( node ) )
-        {
+    private void recurse(List<String> facets, String prefix, Node node)
+            throws RepositoryException {
+        for (Node n : JcrUtils.getChildNodes(node)) {
             String name = prefix + "/" + n.getName();
-            if ( n.hasNodes() )
-            {
-                recurse( facets, name, n );
-            }
-            else
-            {
+            if (n.hasNodes()) {
+                recurse(facets, name, n);
+            } else {
                 // strip leading / first
-                facets.add( name.substring( 1 ) );
+                facets.add(name.substring(1));
             }
         }
     }
 
 
     @Override
-    public <T extends MetadataFacet> T getMetadataFacet( RepositorySession session, String repositoryId, Class<T> clazz, String name ) throws MetadataRepositoryException
-    {
-        if (!metadataService.supportsFacet( clazz )) {
-            log.warn( "The required metadata class is not supported: " + clazz );
+    public <T extends MetadataFacet> T getMetadataFacet(RepositorySession session, String repositoryId, Class<T> clazz, String name) throws MetadataRepositoryException {
+        if (!metadataService.supportsFacet(clazz)) {
+            log.warn("The required metadata class is not supported: " + clazz);
             return null;
         }
-        final Session jcrSession = getSession( session );
-        final MetadataFacetFactory<T> factory = getFacetFactory( clazz );
-        final String facetId = factory.getFacetId( );
-        try
-        {
+        final Session jcrSession = getSession(session);
+        final MetadataFacetFactory<T> factory = getFacetFactory(clazz);
+        final String facetId = factory.getFacetId();
+        try {
             Node root = jcrSession.getRootNode();
-            Node node = root.getNode( getFacetPath( repositoryId, facetId, name ) );
+            Node node = root.getNode(getFacetPath(repositoryId, facetId, name));
 
-            if ( getSupportedFacets().size()==0)
-            {
+            if (getSupportedFacets().size() == 0) {
                 return null;
             }
 
-            return createFacetFromNode( factory, node, repositoryId, name );
-        }
-        catch ( PathNotFoundException e )
-        {
+            return createFacetFromNode(factory, node, repositoryId, name);
+        } catch (PathNotFoundException e) {
             // ignored - the facet doesn't exist, so return null
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
         return null;
     }
@@ -649,148 +567,119 @@ public class JcrMetadataRepository
     }
 
     private <T extends MetadataFacet> T createFacetFromNode(final MetadataFacetFactory<T> factory, final Node node,
-                                                            final String repositoryId, final String name ) throws RepositoryException
-    {
-        if ( factory != null )
-        {
+                                                            final String repositoryId, final String name) throws RepositoryException {
+        if (factory != null) {
             T metadataFacet;
-            if (repositoryId!=null) {
-                metadataFacet = factory.createMetadataFacet( repositoryId, name );
+            if (repositoryId != null) {
+                metadataFacet = factory.createMetadataFacet(repositoryId, name);
             } else {
                 metadataFacet = factory.createMetadataFacet();
             }
             Map<String, String> map = new HashMap<>();
-            for ( Property property : JcrUtils.getProperties( node ) )
-            {
+            for (Property property : JcrUtils.getProperties(node)) {
                 String p = property.getName();
-                if ( !p.startsWith( "jcr:" ) )
-                {
-                    map.put( p, property.getString() );
+                if (!p.startsWith("jcr:")) {
+                    map.put(p, property.getString());
                 }
             }
-            metadataFacet.fromProperties( map );
+            metadataFacet.fromProperties(map);
             return metadataFacet;
         }
         return null;
     }
 
     @Override
-    public void addMetadataFacet( RepositorySession session, String repositoryId, MetadataFacet metadataFacet )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        try
-        {
-            Node repo = getOrAddRepositoryNode( jcrSession, repositoryId );
-            Node facets = JcrUtils.getOrAddNode( repo, "facets", FACETS_FOLDER_TYPE);
+    public void addMetadataFacet(RepositorySession session, String repositoryId, MetadataFacet metadataFacet)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        try {
+            Node repo = getOrAddRepositoryNode(jcrSession, repositoryId);
+            Node facets = JcrUtils.getOrAddNode(repo, "facets", FACETS_FOLDER_TYPE);
 
             String id = metadataFacet.getFacetId();
-            Node facetNode = JcrUtils.getOrAddNode( facets, id, FACET_ID_CONTAINER_TYPE );
+            Node facetNode = JcrUtils.getOrAddNode(facets, id, FACET_ID_CONTAINER_TYPE);
             if (!facetNode.hasProperty("id")) {
                 facetNode.setProperty("id", id);
             }
 
-            Node facetInstance = getOrAddNodeByPath( facetNode, metadataFacet.getName(), FACET_NODE_TYPE, true );
-            if (!facetInstance.hasProperty( "archiva:facetId"))
-            {
-                facetInstance.setProperty( "archiva:facetId", id );
-                facetInstance.setProperty( "archiva:name", metadataFacet.getName( ) );
+            Node facetInstance = getOrAddNodeByPath(facetNode, metadataFacet.getName(), FACET_NODE_TYPE, true);
+            if (!facetInstance.hasProperty("archiva:facetId")) {
+                facetInstance.setProperty("archiva:facetId", id);
+                facetInstance.setProperty("archiva:name", metadataFacet.getName());
             }
 
-            for ( Map.Entry<String, String> entry : metadataFacet.toProperties().entrySet() )
-            {
-                facetInstance.setProperty( entry.getKey(), entry.getValue() );
+            for (Map.Entry<String, String> entry : metadataFacet.toProperties().entrySet()) {
+                facetInstance.setProperty(entry.getKey(), entry.getValue());
             }
             session.save();
-        }
-        catch ( RepositoryException | MetadataSessionException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException | MetadataSessionException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
     @Override
-    public void removeNamespace( RepositorySession session, String repositoryId, String projectId )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        try
-        {
+    public void removeNamespace(RepositorySession session, String repositoryId, String projectId)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        try {
             Node root = jcrSession.getRootNode();
-            String path = getNamespacePath( repositoryId, projectId );
-            if ( root.hasNode( path ) )
-            {
-                Node node = root.getNode( path );
-                if ( node.isNodeType( NAMESPACE_NODE_TYPE ) )
-                {
+            String path = getNamespacePath(repositoryId, projectId);
+            if (root.hasNode(path)) {
+                Node node = root.getNode(path);
+                if (node.isNodeType(NAMESPACE_NODE_TYPE)) {
                     node.remove();
                 }
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
     @Override
-    public void removeMetadataFacets( RepositorySession session, String repositoryId, String facetId )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        try
-        {
+    public void removeMetadataFacets(RepositorySession session, String repositoryId, String facetId)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        try {
             Node root = jcrSession.getRootNode();
-            String path = getFacetPath( repositoryId, facetId );
-            if ( root.hasNode( path ) )
-            {
-                root.getNode( path ).remove();
+            String path = getFacetPath(repositoryId, facetId);
+            if (root.hasNode(path)) {
+                root.getNode(path).remove();
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
     @Override
-    public void removeMetadataFacet( RepositorySession session, String repositoryId, String facetId, String name )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        try
-        {
+    public void removeMetadataFacet(RepositorySession session, String repositoryId, String facetId, String name)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        try {
             Node root = jcrSession.getRootNode();
-            String path = getFacetPath( repositoryId, facetId, name );
-            if ( root.hasNode( path ) )
-            {
-                Node node = root.getNode( path );
-                do
-                {
+            String path = getFacetPath(repositoryId, facetId, name);
+            if (root.hasNode(path)) {
+                Node node = root.getNode(path);
+                do {
                     // also remove empty container nodes
                     Node parent = node.getParent();
                     node.remove();
                     node = parent;
                 }
-                while ( !node.hasNodes() );
+                while (!node.hasNodes());
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
     private StringBuilder buildArtifactByDateRangeQuery(String repoId, ZonedDateTime startTime, ZonedDateTime endTime,
                                                         QueryParameter queryParameter) {
-        StringBuilder q = getArtifactQuery( repoId );
+        StringBuilder q = getArtifactQuery(repoId);
 
-        if ( startTime != null )
-        {
+        if (startTime != null) {
             q.append(" AND [artifact].[whenGathered] >= $start");
         }
-        if ( endTime != null )
-        {
+        if (endTime != null) {
             q.append(" AND [artifact].[whenGathered] <= $end");
         }
         appendQueryParams(q, "artifact", "whenGathered", queryParameter);
@@ -820,25 +709,20 @@ public class JcrMetadataRepository
     }
 
     @Override
-    public List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repoId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
+    public List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repoId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
 
         List<ArtifactMetadata> artifacts;
-        try
-        {
+        try {
             QueryResult result = queryArtifactByDateRange(jcrSession, repoId, startTime, endTime, queryParameter);
 
             artifacts = new ArrayList<>();
-            for ( Node n : JcrUtils.getNodes( result ) )
-            {
-                artifacts.add( getArtifactFromNode( repoId, n ) );
+            for (Node n : JcrUtils.getNodes(result)) {
+                artifacts.add(getArtifactFromNode(repoId, n));
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
         return artifacts;
     }
@@ -846,7 +730,7 @@ public class JcrMetadataRepository
     private Function<Row, Optional<ArtifactMetadata>> getArtifactFromRowFunc(final String repositoryId) {
         return (Row row) -> {
             try {
-                return Optional.of( getArtifactFromNode(repositoryId, row.getNode("artifact")) );
+                return Optional.of(getArtifactFromNode(repositoryId, row.getNode("artifact")));
             } catch (RepositoryException e) {
                 return Optional.empty();
             }
@@ -854,504 +738,425 @@ public class JcrMetadataRepository
     }
 
     @Override
-    public Stream<ArtifactMetadata> getArtifactByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter) throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
+    public Stream<ArtifactMetadata> getArtifactByDateRangeStream(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter) throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
         final QueryResult result = queryArtifactByDateRange(jcrSession, repositoryId, startTime, endTime, queryParameter);
-        final Function<Row, Optional<ArtifactMetadata>> rowFunc = getArtifactFromRowFunc( repositoryId );
-        return StreamSupport.stream( createResultSpliterator( result, rowFunc ), false ).filter( Optional::isPresent ).map( Optional::get );
+        final Function<Row, Optional<ArtifactMetadata>> rowFunc = getArtifactFromRowFunc(repositoryId);
+        return StreamSupport.stream(createResultSpliterator(result, rowFunc), false).filter(Optional::isPresent).map(Optional::get);
     }
 
 
     @Override
-    public List<ArtifactMetadata> getArtifactsByChecksum(RepositorySession session, String repositoryId, String checksum )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
+    public List<ArtifactMetadata> getArtifactsByChecksum(RepositorySession session, String repositoryId, String checksum)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
         List<ArtifactMetadata> artifacts;
 
-        String q = getArtifactQuery( repositoryId ).append(" AND ([artifact].[checksums/*/value] = $checksum)").toString();
+        String q = getArtifactQuery(repositoryId).append(" AND ([artifact].[checksums/*/value] = $checksum)").toString();
 
-        try
-        {
-            Query query = jcrSession.getWorkspace().getQueryManager().createQuery( q, Query.JCR_SQL2 );
+        try {
+            Query query = jcrSession.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2);
             ValueFactory valueFactory = jcrSession.getValueFactory();
-            query.bindValue( "checksum", valueFactory.createValue( checksum ) );
+            query.bindValue("checksum", valueFactory.createValue(checksum));
             QueryResult result = query.execute();
 
             artifacts = new ArrayList<>();
-            for ( Node n : JcrUtils.getNodes( result ) )
-            {
-                artifacts.add( getArtifactFromNode( repositoryId, n ) );
+            for (Node n : JcrUtils.getNodes(result)) {
+                artifacts.add(getArtifactFromNode(repositoryId, n));
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
         return artifacts;
     }
 
-    public List<ArtifactMetadata> runJcrQuery( Session jcrSession, String repositoryId, String q, Map<String, String> bindingParam)
-        throws MetadataRepositoryException
-    {
-        return runJcrQuery( jcrSession, repositoryId, q, bindingParam, true );
+    public List<ArtifactMetadata> runJcrQuery(Session jcrSession, String repositoryId, String q, Map<String, String> bindingParam)
+            throws MetadataRepositoryException {
+        return runJcrQuery(jcrSession, repositoryId, q, bindingParam, true);
     }
 
-    public List<ArtifactMetadata> runJcrQuery( final Session jcrSession, final String repositoryId, final String qParam,
-                                               final Map<String, String> bindingParam, final boolean checkPath )
-        throws MetadataRepositoryException
-    {
+    public List<ArtifactMetadata> runJcrQuery(final Session jcrSession, final String repositoryId, final String qParam,
+                                              final Map<String, String> bindingParam, final boolean checkPath)
+            throws MetadataRepositoryException {
 
         String q = qParam;
         List<ArtifactMetadata> artifacts;
-        if ( repositoryId != null && checkPath )
-        {
-            q += " AND ISDESCENDANTNODE(artifact,'/" + getRepositoryContentPath( repositoryId ) + "')";
+        if (repositoryId != null && checkPath) {
+            q += " AND ISDESCENDANTNODE(artifact,'/" + getRepositoryContentPath(repositoryId) + "')";
         }
 
-        log.info( "Running JCR Query: {}", q );
+        log.info("Running JCR Query: {}", q);
 
-        try
-        {
-            QueryResult result = runNativeJcrQuery( jcrSession, q, bindingParam );
+        try {
+            QueryResult result = runNativeJcrQuery(jcrSession, q, bindingParam);
             artifacts = new ArrayList<>();
             RowIterator rows = result.getRows();
-            while ( rows.hasNext() )
-            {
+            while (rows.hasNext()) {
                 Row row = rows.nextRow();
-                Node node = row.getNode( "artifact" );
-                artifacts.add( getArtifactFromNode( repositoryId, node ) );
+                Node node = row.getNode("artifact");
+                artifacts.add(getArtifactFromNode(repositoryId, node));
             }
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
-        }
-        log.info( "Artifacts found {}", artifacts.size() );
-        for ( ArtifactMetadata meta : artifacts )
-        {
-            log.info( "Artifact: " + meta.getVersion() + " " + meta.getFacetList() );
+        log.info("Artifacts found {}", artifacts.size());
+        for (ArtifactMetadata meta : artifacts) {
+            log.info("Artifact: " + meta.getVersion() + " " + meta.getFacetList());
         }
         return artifacts;
     }
 
-    public QueryResult runNativeJcrQuery( final Session jcrSession, final String q, final Map<String, String> bindingParam) throws MetadataRepositoryException
-    {
-        return runNativeJcrQuery( jcrSession, q, bindingParam, 0, Long.MAX_VALUE );
+    public QueryResult runNativeJcrQuery(final Session jcrSession, final String q, final Map<String, String> bindingParam) throws MetadataRepositoryException {
+        return runNativeJcrQuery(jcrSession, q, bindingParam, 0, Long.MAX_VALUE);
     }
 
-    public QueryResult runNativeJcrQuery( final Session jcrSession, final String q, final Map<String, String> bindingParam, long offset, long maxEntries)
-        throws MetadataRepositoryException
-    {
+    public QueryResult runNativeJcrQuery(final Session jcrSession, final String q, final Map<String, String> bindingParam, long offset, long maxEntries)
+            throws MetadataRepositoryException {
         Map<String, String> bindings;
-        if (bindingParam==null) {
-            bindings = new HashMap<>( );
+        if (bindingParam == null) {
+            bindings = new HashMap<>();
         } else {
             bindings = bindingParam;
         }
 
-        try
-        {
-            log.debug( "Query: offset={}, limit={}, query={}", offset, maxEntries, q );
-            Query query = jcrSession.getWorkspace().getQueryManager().createQuery( q, Query.JCR_SQL2 );
-            query.setLimit( maxEntries );
-            query.setOffset( offset );
+        try {
+            log.debug("Query: offset={}, limit={}, query={}", offset, maxEntries, q);
+            Query query = jcrSession.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2);
+            query.setLimit(maxEntries);
+            query.setOffset(offset);
             ValueFactory valueFactory = jcrSession.getValueFactory();
-            for ( Entry<String, String> entry : bindings.entrySet() )
-            {
-                log.debug( "Binding: {}={}", entry.getKey( ), entry.getValue( ) );
-                Value value = valueFactory.createValue( entry.getValue( ) );
-                log.debug( "Binding value {}={}", entry.getKey( ), value);
-                query.bindValue( entry.getKey(), value );
-            }
-            long start = System.currentTimeMillis( );
-            log.debug( "Execute query {}", query );
+            for (Entry<String, String> entry : bindings.entrySet()) {
+                log.debug("Binding: {}={}", entry.getKey(), entry.getValue());
+                Value value = valueFactory.createValue(entry.getValue());
+                log.debug("Binding value {}={}", entry.getKey(), value);
+                query.bindValue(entry.getKey(), value);
+            }
+            long start = System.currentTimeMillis();
+            log.debug("Execute query {}", query);
             QueryResult result = query.execute();
-            long end = System.currentTimeMillis( );
-            log.info( "JCR Query ran in {} milliseconds: {}", end - start, q );
+            long end = System.currentTimeMillis();
+            log.info("JCR Query ran in {} milliseconds: {}", end - start, q);
             return result;
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
     @Override
-    public List<ArtifactMetadata> getArtifactsByProjectVersionFacet( RepositorySession session, String key, String value, String repositoryId )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        final String q = new StringBuilder( QUERY_ARTIFACTS_BY_PROJECT_VERSION_1 ).append( key ).append( QUERY_ARTIFACTS_BY_PROJECT_VERSION_2 ).toString();
-        return runJcrQuery( jcrSession, repositoryId, q, ImmutableMap.of( "value", value ) );
+    public List<ArtifactMetadata> getArtifactsByProjectVersionFacet(RepositorySession session, String key, String value, String repositoryId)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        final String q = new StringBuilder(QUERY_ARTIFACTS_BY_PROJECT_VERSION_1).append(key).append(QUERY_ARTIFACTS_BY_PROJECT_VERSION_2).toString();
+        return runJcrQuery(jcrSession, repositoryId, q, ImmutableMap.of("value", value));
     }
 
 
     @Override
-    public List<ArtifactMetadata> getArtifactsByAttribute( RepositorySession session, String key, String value, String repositoryId )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        final String q = new StringBuilder( QUERY_ARTIFACTS_BY_METADATA_1 ).append( key ).append( QUERY_ARTIFACTS_BY_METADATA_2 ).toString( );
-        return runJcrQuery( jcrSession, repositoryId, q, ImmutableMap.of( "value", value ) );
+    public List<ArtifactMetadata> getArtifactsByAttribute(RepositorySession session, String key, String value, String repositoryId)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        final String q = new StringBuilder(QUERY_ARTIFACTS_BY_METADATA_1).append(key).append(QUERY_ARTIFACTS_BY_METADATA_2).toString();
+        return runJcrQuery(jcrSession, repositoryId, q, ImmutableMap.of("value", value));
     }
 
 
     @Override
-    public List<ArtifactMetadata> getArtifactsByProjectVersionAttribute( RepositorySession session, String key, String value, String repositoryId )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        final String q = new StringBuilder( QUERY_ARTIFACTS_BY_PROPERTY_1 ).append( key ).append( QUERY_ARTIFACTS_BY_PROPERTY_2 ).toString();
-        return runJcrQuery( jcrSession, repositoryId, q, ImmutableMap.of( "value", value ) );
+    public List<ArtifactMetadata> getArtifactsByProjectVersionAttribute(RepositorySession session, String key, String value, String repositoryId)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        final String q = new StringBuilder(QUERY_ARTIFACTS_BY_PROPERTY_1).append(key).append(QUERY_ARTIFACTS_BY_PROPERTY_2).toString();
+        return runJcrQuery(jcrSession, repositoryId, q, ImmutableMap.of("value", value));
     }
 
 
     @Override
-    public void removeRepository( RepositorySession session, String repositoryId )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        try
-        {
+    public void removeRepository(RepositorySession session, String repositoryId)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        try {
             Node root = jcrSession.getRootNode();
-            String path = getRepositoryPath( repositoryId );
-            if ( root.hasNode( path ) )
-            {
-                root.getNode( path ).remove();
+            String path = getRepositoryPath(repositoryId);
+            if (root.hasNode(path)) {
+                root.getNode(path).remove();
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
     @Override
-    public List<ArtifactMetadata> getArtifacts( RepositorySession session, String repositoryId )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
+    public List<ArtifactMetadata> getArtifacts(RepositorySession session, String repositoryId)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
         List<ArtifactMetadata> artifacts;
 
-        String q = getArtifactQuery( repositoryId ).toString();
+        String q = getArtifactQuery(repositoryId).toString();
 
-        try
-        {
-            Query query = jcrSession.getWorkspace().getQueryManager().createQuery( q, Query.JCR_SQL2 );
+        try {
+            Query query = jcrSession.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2);
             QueryResult result = query.execute();
 
             artifacts = new ArrayList<>();
-            for ( Node n : JcrUtils.getNodes( result ) )
-            {
-                if ( n.isNodeType( ARTIFACT_NODE_TYPE ) )
-                {
-                    artifacts.add( getArtifactFromNode( repositoryId, n ) );
+            for (Node n : JcrUtils.getNodes(result)) {
+                if (n.isNodeType(ARTIFACT_NODE_TYPE)) {
+                    artifacts.add(getArtifactFromNode(repositoryId, n));
                 }
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
         return artifacts;
     }
 
-    private static StringBuilder getArtifactQuery( String repositoryId )
-    {
-        return new StringBuilder(QUERY_ARTIFACT_1).append(getRepositoryContentPath( repositoryId )).append(QUERY_ARTIFACT_2);
+    private static StringBuilder getArtifactQuery(String repositoryId) {
+        return new StringBuilder(QUERY_ARTIFACT_1).append(getRepositoryContentPath(repositoryId)).append(QUERY_ARTIFACT_2);
     }
 
     @Override
-    public ProjectMetadata getProject( RepositorySession session, String repositoryId, String namespace, String projectId )
-        throws MetadataResolutionException
-    {
+    public ProjectMetadata getProject(RepositorySession session, String repositoryId, String namespace, String projectId)
+            throws MetadataResolutionException {
         final Session jcrSession;
-        try
-        {
-            jcrSession = getSession( session );
-        }
-        catch ( MetadataRepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage() );
+        try {
+            jcrSession = getSession(session);
+        } catch (MetadataRepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage());
         }
         ProjectMetadata metadata = null;
 
-        try
-        {
+        try {
             Node root = jcrSession.getRootNode();
 
             // basically just checking it exists
-            String path = getProjectPath( repositoryId, namespace, projectId );
-            if ( root.hasNode( path ) )
-            {
+            String path = getProjectPath(repositoryId, namespace, projectId);
+            if (root.hasNode(path)) {
                 metadata = new ProjectMetadata();
-                metadata.setId( projectId );
-                metadata.setNamespace( namespace );
+                metadata.setId(projectId);
+                metadata.setNamespace(namespace);
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage(), e);
         }
 
         return metadata;
     }
 
+    private static Optional<License> getLicense(Node licenseNode) {
+        try {
+            String licenseName = licenseNode.getName();
+            String licenseUrl = getPropertyString(licenseNode, "url");
+            License license = new License();
+            license.setName(licenseName);
+            license.setUrl(licenseUrl);
+            return Optional.of(license);
+        } catch (RepositoryException e) {
+            return Optional.empty();
+        }
+    }
+
+    private static Optional<MailingList> getMailinglist(Node mailinglistNode) {
+        try {
+            String mailingListName = mailinglistNode.getName();
+        MailingList mailinglist = new MailingList();
+        mailinglist.setName(mailingListName);
+        mailinglist.setMainArchiveUrl(getPropertyString(mailinglistNode, "archive"));
+        String n = "otherArchives";
+        if (mailinglistNode.hasProperty(n)) {
+            mailinglist.setOtherArchives(Arrays.asList(getPropertyString(mailinglistNode, n).split(",")));
+        } else {
+            mailinglist.setOtherArchives(Collections.<String>emptyList());
+        }
+        mailinglist.setPostAddress(getPropertyString(mailinglistNode, "post"));
+        mailinglist.setSubscribeAddress(getPropertyString(mailinglistNode, "subscribe"));
+        mailinglist.setUnsubscribeAddress(getPropertyString(mailinglistNode, "unsubscribe"));
+        return Optional.of(mailinglist);
+        } catch (RepositoryException e) {
+            return Optional.empty();
+        }
+
+    }
+
     @Override
-    public ProjectVersionMetadata getProjectVersion( RepositorySession session, String repositoryId, String namespace, String projectId,
-                                                     String projectVersion )
-        throws MetadataResolutionException
-    {
+    public ProjectVersionMetadata getProjectVersion(RepositorySession session, String repositoryId, String namespace, String projectId,
+                                                    String projectVersion)
+            throws MetadataResolutionException {
         final Session jcrSession;
-        try
-        {
-            jcrSession = getSession( session );
-        }
-        catch ( MetadataRepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage() );
+        try {
+            jcrSession = getSession(session);
+        } catch (MetadataRepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage());
         }
         ProjectVersionMetadata versionMetadata;
 
-        try
-        {
+        try {
             Node root = jcrSession.getRootNode();
 
-            String path = getProjectVersionPath( repositoryId, namespace, projectId, projectVersion );
-            if ( !root.hasNode( path ) )
-            {
+            String path = getProjectVersionPath(repositoryId, namespace, projectId, projectVersion);
+            if (!root.hasNode(path)) {
                 return null;
             }
 
-            Node node = root.getNode( path );
+            Node node = root.getNode(path);
 
             versionMetadata = new ProjectVersionMetadata();
-            versionMetadata.setId( projectVersion );
-            versionMetadata.setName( getPropertyString( node, "name" ) );
-            versionMetadata.setDescription( getPropertyString( node, "description" ) );
-            versionMetadata.setUrl( getPropertyString( node, "url" ) );
+            versionMetadata.setId(projectVersion);
+            versionMetadata.setName(getPropertyString(node, "name"));
+            versionMetadata.setDescription(getPropertyString(node, "description"));
+            versionMetadata.setUrl(getPropertyString(node, "url"));
             versionMetadata.setIncomplete(
-                node.hasProperty( "incomplete" ) && node.getProperty( "incomplete" ).getBoolean() );
+                    node.hasProperty("incomplete") && node.getProperty("incomplete").getBoolean());
 
             // FIXME: decide how to treat these in the content repo
-            String scmConnection = getPropertyString( node, "scm.connection" );
-            String scmDeveloperConnection = getPropertyString( node, "scm.developerConnection" );
-            String scmUrl = getPropertyString( node, "scm.url" );
-            if ( scmConnection != null || scmDeveloperConnection != null || scmUrl != null )
-            {
+            String scmConnection = getPropertyString(node, "scm.connection");
+            String scmDeveloperConnection = getPropertyString(node, "scm.developerConnection");
+            String scmUrl = getPropertyString(node, "scm.url");
+            if (scmConnection != null || scmDeveloperConnection != null || scmUrl != null) {
                 Scm scm = new Scm();
-                scm.setConnection( scmConnection );
-                scm.setDeveloperConnection( scmDeveloperConnection );
-                scm.setUrl( scmUrl );
-                versionMetadata.setScm( scm );
+                scm.setConnection(scmConnection);
+                scm.setDeveloperConnection(scmDeveloperConnection);
+                scm.setUrl(scmUrl);
+                versionMetadata.setScm(scm);
             }
 
-            String ciSystem = getPropertyString( node, "ci.system" );
-            String ciUrl = getPropertyString( node, "ci.url" );
-            if ( ciSystem != null || ciUrl != null )
-            {
+            String ciSystem = getPropertyString(node, "ci.system");
+            String ciUrl = getPropertyString(node, "ci.url");
+            if (ciSystem != null || ciUrl != null) {
                 CiManagement ci = new CiManagement();
-                ci.setSystem( ciSystem );
-                ci.setUrl( ciUrl );
-                versionMetadata.setCiManagement( ci );
+                ci.setSystem(ciSystem);
+                ci.setUrl(ciUrl);
+                versionMetadata.setCiManagement(ci);
             }
 
-            String issueSystem = getPropertyString( node, "issue.system" );
-            String issueUrl = getPropertyString( node, "issue.url" );
-            if ( issueSystem != null || issueUrl != null )
-            {
+            String issueSystem = getPropertyString(node, "issue.system");
+            String issueUrl = getPropertyString(node, "issue.url");
+            if (issueSystem != null || issueUrl != null) {
                 IssueManagement issueManagement = new IssueManagement();
-                issueManagement.setSystem( issueSystem );
-                issueManagement.setUrl( issueUrl );
-                versionMetadata.setIssueManagement( issueManagement );
+                issueManagement.setSystem(issueSystem);
+                issueManagement.setUrl(issueUrl);
+                versionMetadata.setIssueManagement(issueManagement);
             }
 
-            String orgName = getPropertyString( node, "org.name" );
-            String orgUrl = getPropertyString( node, "org.url" );
-            if ( orgName != null || orgUrl != null )
-            {
+            String orgName = getPropertyString(node, "org.name");
+            String orgUrl = getPropertyString(node, "org.url");
+            if (orgName != null || orgUrl != null) {
                 Organization org = new Organization();
-                org.setName( orgName );
-                org.setUrl( orgUrl );
-                versionMetadata.setOrganization( org );
-            }
-
-            boolean done = false;
-            int i = 0;
-            while ( !done )
-            {
-                String licenseName = getPropertyString( node, "license." + i + ".name" );
-                String licenseUrl = getPropertyString( node, "license." + i + ".url" );
-                if ( licenseName != null || licenseUrl != null )
-                {
-                    License license = new License();
-                    license.setName( licenseName );
-                    license.setUrl( licenseUrl );
-                    versionMetadata.addLicense( license );
-                }
-                else
-                {
-                    done = true;
-                }
-                i++;
-            }
-
-            done = false;
-            i = 0;
-            while ( !done )
-            {
-                String mailingListName = getPropertyString( node, "mailingList." + i + ".name" );
-                if ( mailingListName != null )
-                {
-                    MailingList mailingList = new MailingList();
-                    mailingList.setName( mailingListName );
-                    mailingList.setMainArchiveUrl( getPropertyString( node, "mailingList." + i + ".archive" ) );
-                    String n = "mailingList." + i + ".otherArchives";
-                    if ( node.hasProperty( n ) )
-                    {
-                        mailingList.setOtherArchives( Arrays.asList( getPropertyString( node, n ).split( "," ) ) );
-                    }
-                    else
-                    {
-                        mailingList.setOtherArchives( Collections.<String>emptyList() );
-                    }
-                    mailingList.setPostAddress( getPropertyString( node, "mailingList." + i + ".post" ) );
-                    mailingList.setSubscribeAddress( getPropertyString( node, "mailingList." + i + ".subscribe" ) );
-                    mailingList.setUnsubscribeAddress( getPropertyString( node, "mailingList." + i + ".unsubscribe" ) );
-                    versionMetadata.addMailingList( mailingList );
-                }
-                else
-                {
-                    done = true;
-                }
-                i++;
-            }
-
-            if ( node.hasNode( "dependencies" ) )
-            {
-                Node dependenciesNode = node.getNode( "dependencies" );
-                for ( Node n : JcrUtils.getChildNodes( dependenciesNode ) )
-                {
-                    if ( n.isNodeType( DEPENDENCY_NODE_TYPE ) )
-                    {
+                org.setName(orgName);
+                org.setUrl(orgUrl);
+                versionMetadata.setOrganization(org);
+            }
+
+            if (node.hasNode("licenses")) {
+                Node licensesListNode = node.getNode("licenses");
+                List<License> licenseList = StreamSupport.stream(JcrUtils.getChildNodes(licensesListNode).spliterator(),false)
+                        .map(JcrMetadataRepository::getLicense).filter(Optional::isPresent)
+                        .map(Optional::get).sorted().collect(Collectors.toList());
+                versionMetadata.setLicenses(licenseList);
+            }
+            if (node.hasNode("mailinglists")) {
+                Node mailinglistsListNode = node.getNode("mailinglists");
+                List<MailingList> mailinglistList = StreamSupport.stream(JcrUtils.getChildNodes(mailinglistsListNode).spliterator(), false)
+                        .map(JcrMetadataRepository::getMailinglist)
+                        .filter(Optional::isPresent)
+                        .map(Optional::get)
+                        .sorted().collect(Collectors.toList());
+                versionMetadata.setMailingLists(mailinglistList);
+            }
+
+            if (node.hasNode("dependencies")) {
+                Node dependenciesNode = node.getNode("dependencies");
+                for (Node n : JcrUtils.getChildNodes(dependenciesNode)) {
+                    if (n.isNodeType(DEPENDENCY_NODE_TYPE)) {
                         Dependency dependency = new Dependency();
                         // FIXME: correct these properties
-                        dependency.setArtifactId( getPropertyString( n, "artifactId" ) );
-                        dependency.setGroupId( getPropertyString( n, "groupId" ) );
-                        dependency.setClassifier( getPropertyString( n, "classifier" ) );
-                        dependency.setOptional( Boolean.valueOf( getPropertyString( n, "optional" ) ) );
-                        dependency.setScope( getPropertyString( n, "scope" ) );
-                        dependency.setSystemPath( getPropertyString( n, "systemPath" ) );
-                        dependency.setType( getPropertyString( n, "type" ) );
-                        dependency.setVersion( getPropertyString( n, "version" ) );
-                        versionMetadata.addDependency( dependency );
+                        dependency.setNamespace(getPropertyString(n, "namespace"));
+                        dependency.setProjectId(getPropertyString(n, "projectId"));
+                        dependency.setVersion(getPropertyString(n, "version"));
+                        dependency.setArtifactId(getPropertyString(n, "artifactId"));
+                        dependency.setClassifier(getPropertyString(n, "classifier"));
+                        dependency.setOptional(Boolean.valueOf(getPropertyString(n, "optional")));
+                        dependency.setScope(getPropertyString(n, "scope"));
+                        dependency.setSystemPath(getPropertyString(n, "systemPath"));
+                        dependency.setType(getPropertyString(n, "type"));
+                        versionMetadata.addDependency(dependency);
                     }
                 }
             }
 
-            retrieveFacetProperties( versionMetadata, node );
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage(), e );
+            retrieveFacetProperties(versionMetadata, node);
+        } catch (RepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage(), e);
         }
 
         return versionMetadata;
     }
 
-    private void retrieveFacetProperties( FacetedMetadata metadata, Node node ) throws RepositoryException
-    {
-        for ( Node n : JcrUtils.getChildNodes( node ) )
-        {
-            if ( n.isNodeType( FACET_NODE_TYPE ) )
-            {
+    private void retrieveFacetProperties(FacetedMetadata metadata, Node node) throws RepositoryException {
+        for (Node n : JcrUtils.getChildNodes(node)) {
+            if (n.isNodeType(FACET_NODE_TYPE)) {
                 String name = n.getName();
-                MetadataFacetFactory factory = metadataService.getFactory( name );
-                if ( factory == null )
-                {
-                    log.error( "Attempted to load unknown project version metadata facet: {}", name );
-                }
-                else
-                {
+                MetadataFacetFactory factory = metadataService.getFactory(name);
+                if (factory == null) {
+                    log.error("Attempted to load unknown project version metadata facet: {}", name);
+                } else {
                     MetadataFacet facet = createFacetFromNode(factory, n);
-                    metadata.addFacet( facet );
+                    metadata.addFacet(facet);
                 }
             }
         }
     }
 
     @Override
-    public List<String> getArtifactVersions( RepositorySession session, String repositoryId, String namespace, String projectId,
-                                             String projectVersion )
-        throws MetadataResolutionException
-    {
+    public List<String> getArtifactVersions(RepositorySession session, String repositoryId, String namespace, String projectId,
+                                            String projectVersion)
+            throws MetadataResolutionException {
         final Session jcrSession;
-        try
-        {
-            jcrSession = getSession( session );
-        }
-        catch ( MetadataRepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage() );
+        try {
+            jcrSession = getSession(session);
+        } catch (MetadataRepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage());
         }
         Set<String> versions = new LinkedHashSet<String>();
 
-        try
-        {
+        try {
             Node root = jcrSession.getRootNode();
 
-            Node node = root.getNode( getProjectVersionPath( repositoryId, namespace, projectId, projectVersion ) );
+            Node node = root.getNode(getProjectVersionPath(repositoryId, namespace, projectId, projectVersion));
 
-            for ( Node n : JcrUtils.getChildNodes( node ) )
-            {
-                versions.add( n.getProperty( "version" ).getString() );
+            for (Node n : JcrUtils.getChildNodes(node)) {
+                versions.add(n.getProperty("version").getString());
             }
-        }
-        catch ( PathNotFoundException e )
-        {
+        } catch (PathNotFoundException e) {
             // ignore repo not found for now
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage(), e);
         }
 
-        return new ArrayList<>( versions );
+        return new ArrayList<>(versions);
     }
 
     @Override
-    public List<ProjectVersionReference> getProjectReferences( RepositorySession session, String repositoryId, String namespace,
-                                                               String projectId, String projectVersion )
-        throws MetadataResolutionException
-    {
+    public List<ProjectVersionReference> getProjectReferences(RepositorySession session, String repositoryId, String namespace,
+                                                              String projectId, String projectVersion)
+            throws MetadataResolutionException {
         final Session jcrSession;
-        try
-        {
-            jcrSession = getSession( session );
-        }
-        catch ( MetadataRepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage() );
+        try {
+            jcrSession = getSession(session);
+        } catch (MetadataRepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage());
         }
 
         List<ProjectVersionReference> references = new ArrayList<>();
 
         // TODO: bind variables instead
         String q = "SELECT * FROM [archiva:dependency] WHERE ISDESCENDANTNODE([/repositories/" + repositoryId
-            + "/content]) AND [groupId]='" + namespace + "' AND [artifactId]='" + projectId + "'";
-        if ( projectVersion != null )
-        {
+                + "/content]) AND [namespace]='" + namespace + "' AND [artifactId]='" + projectId + "'";
+        if (projectVersion != null) {
             q += " AND [version]='" + projectVersion + "'";
         }
-        try
-        {
-            Query query = jcrSession.getWorkspace().getQueryManager().createQuery( q, Query.JCR_SQL2 );
+        try {
+            Query query = jcrSession.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2);
             QueryResult result = query.execute();
 
-            for ( Node n : JcrUtils.getNodes( result ) )
-            {
+            for (Node n : JcrUtils.getNodes(result)) {
                 n = n.getParent(); // dependencies grouping element
 
                 n = n.getParent(); // project version
@@ -1361,104 +1166,82 @@ public class JcrMetadataRepository
                 String usedByProject = n.getName();
 
                 n = n.getParent(); // namespace
-                String usedByNamespace = n.getProperty( "namespace" ).getString();
+                String usedByNamespace = n.getProperty("namespace").getString();
 
                 ProjectVersionReference ref = new ProjectVersionReference();
-                ref.setNamespace( usedByNamespace );
-                ref.setProjectId( usedByProject );
-                ref.setProjectVersion( usedByProjectVersion );
-                ref.setReferenceType( ProjectVersionReference.ReferenceType.DEPENDENCY );
-                references.add( ref );
+                ref.setNamespace(usedByNamespace);
+                ref.setProjectId(usedByProject);
+                ref.setProjectVersion(usedByProjectVersion);
+                ref.setReferenceType(ProjectVersionReference.ReferenceType.DEPENDENCY);
+                references.add(ref);
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage(), e);
         }
 
         return references;
     }
 
     @Override
-    public List<String> getRootNamespaces( RepositorySession session, String repositoryId )
-        throws MetadataResolutionException
-    {
-        return this.getChildNamespaces(session , repositoryId, null );
+    public List<String> getRootNamespaces(RepositorySession session, String repositoryId)
+            throws MetadataResolutionException {
+        return this.getChildNamespaces(session, repositoryId, null);
     }
 
     @Override
-    public List<String> getChildNamespaces( RepositorySession session, String repositoryId, String baseNamespace )
-        throws MetadataResolutionException
-    {
+    public List<String> getChildNamespaces(RepositorySession session, String repositoryId, String baseNamespace)
+            throws MetadataResolutionException {
         String path = baseNamespace != null
-            ? getNamespacePath( repositoryId, baseNamespace )
-            : getRepositoryContentPath( repositoryId );
+                ? getNamespacePath(repositoryId, baseNamespace)
+                : getRepositoryContentPath(repositoryId);
 
-        try
-        {
-            return getNodeNames( getSession(session), path, NAMESPACE_NODE_TYPE );
-        }
-        catch ( MetadataRepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage( ) );
+        try {
+            return getNodeNames(getSession(session), path, NAMESPACE_NODE_TYPE);
+        } catch (MetadataRepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage());
         }
     }
 
     @Override
-    public List<String> getProjects( RepositorySession session, String repositoryId, String namespace )
-        throws MetadataResolutionException
-    {
-        try
-        {
-            return getNodeNames( getSession(session), getNamespacePath( repositoryId, namespace ), org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_NODE_TYPE );
-        }
-        catch ( MetadataRepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage( ) );
+    public List<String> getProjects(RepositorySession session, String repositoryId, String namespace)
+            throws MetadataResolutionException {
+        try {
+            return getNodeNames(getSession(session), getNamespacePath(repositoryId, namespace), org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_NODE_TYPE);
+        } catch (MetadataRepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage());
         }
     }
 
     @Override
-    public List<String> getProjectVersions( RepositorySession session, String repositoryId, String namespace, String projectId )
-        throws MetadataResolutionException
-    {
-        try
-        {
-            return getNodeNames( getSession(session), getProjectPath( repositoryId, namespace, projectId ), PROJECT_VERSION_NODE_TYPE );
-        }
-        catch ( MetadataRepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage( ) );
+    public List<String> getProjectVersions(RepositorySession session, String repositoryId, String namespace, String projectId)
+            throws MetadataResolutionException {
+        try {
+            return getNodeNames(getSession(session), getProjectPath(repositoryId, namespace, projectId), PROJECT_VERSION_NODE_TYPE);
+        } catch (MetadataRepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage());
         }
     }
 
     @Override
-    public void removeTimestampedArtifact( RepositorySession session, ArtifactMetadata artifactMetadata, String baseVersion )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
+    public void removeTimestampedArtifact(RepositorySession session, ArtifactMetadata artifactMetadata, String baseVersion)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
         String repositoryId = artifactMetadata.getRepositoryId();
 
-        try
-        {
+        try {
             Node root = jcrSession.getRootNode();
             String path =
-                getProjectVersionPath( repositoryId, artifactMetadata.getNamespace(), artifactMetadata.getProject(),
-                                       baseVersion );
-
-            if ( root.hasNode( path ) )
-            {
-                Node node = root.getNode( path );
-
-                for ( Node n : JcrUtils.getChildNodes( node ) )
-                {
-                    if ( n.isNodeType( ARTIFACT_NODE_TYPE ) )
-                    {
-                        if ( n.hasProperty( "version" ) )
-                        {
-                            String version = n.getProperty( "version" ).getString();
-                            if ( StringUtils.equals( version, artifactMetadata.getVersion() ) )
-                            {
+                    getProjectVersionPath(repositoryId, artifactMetadata.getNamespace(), artifactMetadata.getProject(),
+                            baseVersion);
+
+            if (root.hasNode(path)) {
+                Node node = root.getNode(path);
+
+                for (Node n : JcrUtils.getChildNodes(node)) {
+                    if (n.isNodeType(ARTIFACT_NODE_TYPE)) {
+                        if (n.hasProperty("version")) {
+                            String version = n.getProperty("version").getString();
+                            if (StringUtils.equals(version, artifactMetadata.getVersion())) {
                                 n.remove();
                             }
                         }
@@ -1466,10 +1249,8 @@ public class JcrMetadataRepository
                     }
                 }
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
 
 
@@ -1477,142 +1258,111 @@ public class JcrMetadataRepository
 
 
     @Override
-    public void removeProjectVersion( RepositorySession session, String repoId, String namespace, String projectId, String projectVersion )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        try
-        {
-
-            String path = getProjectPath( repoId, namespace, projectId );
+    public void removeProjectVersion(RepositorySession session, String repoId, String namespace, String projectId, String projectVersion)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        try {
+
+            String path = getProjectPath(repoId, namespace, projectId);
             Node root = jcrSession.getRootNode();
 
-            Node nodeAtPath = root.getNode( path );
+            Node nodeAtPath = root.getNode(path);
 
-            for ( Node node : JcrUtils.getChildNodes( nodeAtPath ) )
-            {
-                if ( node.isNodeType( PROJECT_VERSION_NODE_TYPE ) && StringUtils.equals( projectVersion,
-                                                                                         node.getName() ) )
-                {
+            for (Node node : JcrUtils.getChildNodes(nodeAtPath)) {
+                if (node.isNodeType(PROJECT_VERSION_NODE_TYPE) && StringUtils.equals(projectVersion,
+                        node.getName())) {
                     node.remove();
                 }
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
     @Override
-    public void removeArtifact( RepositorySession session, String repositoryId, String namespace, String projectId, String projectVersion,
-                                String id )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        try
-        {
+    public void removeArtifact(RepositorySession session, String repositoryId, String namespace, String projectId, String projectVersion,
+                               String id)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        try {
             Node root = jcrSession.getRootNode();
-            String path = getArtifactPath( repositoryId, namespace, projectId, projectVersion, id );
-            if ( root.hasNode( path ) )
-            {
-                root.getNode( path ).remove();
+            String path = getArtifactPath(repositoryId, namespace, projectId, projectVersion, id);
+            if (root.hasNode(path)) {
+                root.getNode(path).remove();
             }
 
             // remove version
 
-            path = getProjectPath( repositoryId, namespace, projectId );
+            path = getProjectPath(repositoryId, namespace, projectId);
 
-            Node nodeAtPath = root.getNode( path );
+            Node nodeAtPath = root.getNode(path);
 
-            for ( Node node : JcrUtils.getChildNodes( nodeAtPath ) )
-            {
-                if ( node.isNodeType( PROJECT_VERSION_NODE_TYPE ) //
-                    && StringUtils.equals( node.getName(), projectVersion ) )
-                {
+            for (Node node : JcrUtils.getChildNodes(nodeAtPath)) {
+                if (node.isNodeType(PROJECT_VERSION_NODE_TYPE) //
+                        && StringUtils.equals(node.getName(), projectVersion)) {
                     node.remove();
                 }
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
     @Override
-    public void removeFacetFromArtifact( RepositorySession session, String repositoryId, String namespace, String project, String projectVersion,
-                                         MetadataFacet metadataFacet )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
-        try
-        {
+    public void removeFacetFromArtifact(RepositorySession session, String repositoryId, String namespace, String project, String projectVersion,
+                                        MetadataFacet metadataFacet)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
+        try {
             Node root = jcrSession.getRootNode();
-            String path = getProjectVersionPath( repositoryId, namespace, project, projectVersion );
-
-            if ( root.hasNode( path ) )
-            {
-                Node node = root.getNode( path );
-
-                for ( Node n : JcrUtils.getChildNodes( node ) )
-                {
-                    if ( n.isNodeType( ARTIFACT_NODE_TYPE ) )
-                    {
-                        ArtifactMetadata artifactMetadata = getArtifactFromNode( repositoryId, n );
-                        log.debug( "artifactMetadata: {}", artifactMetadata );
-                        MetadataFacet metadataFacetToRemove = artifactMetadata.getFacet( metadataFacet.getFacetId() );
-                        if ( metadataFacetToRemove != null && metadataFacet.equals( metadataFacetToRemove ) )
-                        {
+            String path = getProjectVersionPath(repositoryId, namespace, project, projectVersion);
+
+            if (root.hasNode(path)) {
+                Node node = root.getNode(path);
+
+                for (Node n : JcrUtils.getChildNodes(node)) {
+                    if (n.isNodeType(ARTIFACT_NODE_TYPE)) {
+                        ArtifactMetadata artifactMetadata = getArtifactFromNode(repositoryId, n);
+                        log.debug("artifactMetadata: {}", artifactMetadata);
+                        MetadataFacet metadataFacetToRemove = artifactMetadata.getFacet(metadataFacet.getFacetId());
+                        if (metadataFacetToRemove != null && metadataFacet.equals(metadataFacetToRemove)) {
                             n.remove();
                         }
                     }
                 }
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
     @Override
-    public List<ArtifactMetadata> getArtifacts( RepositorySession session, String repositoryId, String namespace, String projectId,
-                                                String projectVersion )
-        throws MetadataResolutionException
-    {
+    public List<ArtifactMetadata> getArtifacts(RepositorySession session, String repositoryId, String namespace, String projectId,
+                                               String projectVersion)
+            throws MetadataResolutionException {
         final Session jcrSession;
-        try
-        {
-            jcrSession = getSession( session );
-        }
-        catch ( MetadataRepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage( ) );
+        try {
+            jcrSession = getSession(session);
+        } catch (MetadataRepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage());
         }
         List<ArtifactMetadata> artifacts = new ArrayList<>();
 
-        try
-        {
+        try {
             Node root = jcrSession.getRootNode();
-            String path = getProjectVersionPath( repositoryId, namespace, projectId, projectVersion );
+            String path = getProjectVersionPath(repositoryId, namespace, projectId, projectVersion);
 
-            if ( root.hasNode( path ) )
-            {
-                Node node = root.getNode( path );
+            if (root.hasNode(path)) {
+                Node node = root.getNode(path);
 
-                for ( Node n : JcrUtils.getChildNodes( node ) )
-                {
-                    if ( n.isNodeType( ARTIFACT_NODE_TYPE ) )
-                    {
-                        artifacts.add( getArtifactFromNode( repositoryId, n ) );
+                for (Node n : JcrUtils.getChildNodes(node)) {
+                    if (n.isNodeType(ARTIFACT_NODE_TYPE)) {
+                        artifacts.add(getArtifactFromNode(repositoryId, n));
                     }
                 }
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage(), e);
         }
 
         return artifacts;
@@ -1621,8 +1371,7 @@ public class JcrMetadataRepository
 
     @Override
     public void close()
-        throws MetadataRepositoryException
-    {
+            throws MetadataRepositoryException {
     }
 
 
@@ -1630,335 +1379,307 @@ public class JcrMetadataRepository
      * Exact is ignored as we can't do exact search in any property, we need a key
      */
     @Override
-    public List<ArtifactMetadata> searchArtifacts( RepositorySession session, String repositoryId, String text, boolean exact )
-        throws MetadataRepositoryException
-    {
-        return searchArtifacts( session, repositoryId, null, text, exact );
+    public List<ArtifactMetadata> searchArtifacts(RepositorySession session, String repositoryId, String text, boolean exact)
+            throws MetadataRepositoryException {
+        return searchArtifacts(session, repositoryId, null, text, exact);
     }
 
     @Override
-    public List<ArtifactMetadata> searchArtifacts( RepositorySession session, String repositoryId, String key, String text, boolean exact )
-        throws MetadataRepositoryException
-    {
-        final Session jcrSession = getSession( session );
+    public List<ArtifactMetadata> searchArtifacts(RepositorySession session, String repositoryId, String key, String text, boolean exact)
+            throws MetadataRepositoryException {
+        final Session jcrSession = getSession(session);
         String theKey = key == null ? "*" : "[" + key + "]";
         String projectVersionCondition =
-            exact ? "(projectVersion." + theKey + " = $value)" : "contains([projectVersion]." + theKey + ", $value)";
+                exact ? "(projectVersion." + theKey + " = $value)" : "contains([projectVersion]." + theKey + ", $value)";
         String facetCondition = exact ? "(facet." + theKey + " = $value)" : "contains([facet]." + theKey + ", $value)";
         String descendantCondition = repositoryId == null ?
-            " AND [projectVersion].[jcr:path] LIKE '/repositories/%/content/%'" :
-            " AND ISDESCENDANTNODE(projectVersion,'/" + getRepositoryContentPath( repositoryId ) + "')";
-        List<ArtifactMetadata> result = new ArrayList<>( );
-        if (key==null || (key!=null && Arrays.binarySearch( PROJECT_VERSION_VERSION_PROPERTIES, key )>=0))
-        {
+                " AND [projectVersion].[jcr:path] LIKE '/repositories/%/content/%'" :
+                " AND ISDESCENDANTNODE(projectVersion,'/" + getRepositoryContentPath(repositoryId) + "')";
+        List<ArtifactMetadata> result = new ArrayList<>();
+        if (key == null || (key != null && Arrays.binarySearch(PROJECT_VERSION_VERSION_PROPERTIES, key) >= 0)) {
             // We search only for project version properties if the key is a valid property name
             String q1 =
-                "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE
-                    + "] AS projectVersion LEFT OUTER JOIN [" + ARTIFACT_NODE_TYPE
-                    + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) WHERE " + projectVersionCondition + descendantCondition;
-             result.addAll(runJcrQuery( jcrSession, repositoryId, q1, ImmutableMap.of( "value", text ), false ));
+                    "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE
+                            + "] AS projectVersion LEFT OUTER JOIN [" + ARTIFACT_NODE_TYPE
+                            + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) WHERE " + projectVersionCondition + descendantCondition;
+            result.addAll(runJcrQuery(jcrSession, repositoryId, q1, ImmutableMap.of("value", text), false));
         }
         String q2 =
-            "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE
-                + "] AS projectVersion LEFT OUTER JOIN [" + ARTIFACT_NODE_TYPE
-                + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) LEFT OUTER JOIN [" + FACET_NODE_TYPE
-                + "] AS facet ON ISCHILDNODE(facet, projectVersion) WHERE " + facetCondition + descendantCondition;
-        result.addAll( runJcrQuery( jcrSession, repositoryId, q2, ImmutableMap.of( "value", text ), false ) );
+                "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE
+                        + "] AS projectVersion LEFT OUTER JOIN [" + ARTIFACT_NODE_TYPE
+                        + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) LEFT OUTER JOIN [" + FACET_NODE_TYPE
+                        + "] AS facet ON ISCHILDNODE(facet, projectVersion) WHERE " + facetCondition + descendantCondition;
+        result.addAll(runJcrQuery(jcrSession, repositoryId, q2, ImmutableMap.of("value", text), false));
         return result;
     }
 
-    private ArtifactMetadata getArtifactFromNode( String repositoryId, Node artifactNode )
-        throws RepositoryException
-    {
+    private ArtifactMetadata getArtifactFromNode(String repositoryId, Node artifactNode)
+            throws RepositoryException {
         String id = artifactNode.getName();
 
         ArtifactMetadata artifact = new ArtifactMetadata();
-        artifact.setId( id );
-        artifact.setRepositoryId( repositoryId == null ? artifactNode.getAncestor( 2 ).getName() : repositoryId );
+        artifact.setId(id);
+        artifact.setRepositoryId(repositoryId == null ? artifactNode.getAncestor(2).getName() : repositoryId);
 
         Node projectVersionNode = artifactNode.getParent();
         Node projectNode = projectVersionNode.getParent();
         Node namespaceNode = projectNode.getParent();
 
-        artifact.setNamespace( namespaceNode.getProperty( "namespace" ).getString() );
-        artifact.setProject( projectNode.getName() );
-        artifact.setProjectVersion( projectVersionNode.getName() );
-        artifact.setVersion( artifactNode.hasProperty( "version" )
-                                 ? artifactNode.getProperty( "version" ).getString()
-                                 : projectVersionNode.getName() );
+        artifact.setNamespace(namespaceNode.getProperty("namespace").getString());
+        artifact.setProject(projectNode.getName());
+        artifact.setProjectVersion(projectVersionNode.getName());
+        artifact.setVersion(artifactNode.hasProperty("version")
+                ? artifactNode.getProperty("version").getString()
+                : projectVersionNode.getName());
 
-        if ( artifactNode.hasProperty( JCR_LAST_MODIFIED ) )
-        {
-            artifact.setFileLastModified( artifactNode.getProperty( JCR_LAST_MODIFIED ).getDate().getTimeInMillis() );
+        if (artifactNode.hasProperty(JCR_LAST_MODIFIED)) {
+            artifact.setFileLastModified(artifactNode.getProperty(JCR_LAST_MODIFIED).getDate().getTimeInMillis());
         }
 
-        if ( artifactNode.hasProperty( "whenGathered" ) )
-        {
+        if (artifactNode.hasProperty("whenGathered")) {
             Calendar cal = artifactNode.getProperty("whenGathered").getDate();
-            artifact.setWhenGathered( ZonedDateTime.ofInstant(cal.toInstant(), cal.getTimeZone().toZoneId()));
+            artifact.setWhenGathered(ZonedDateTime.ofInstant(cal.toInstant(), cal.getTimeZone().toZoneId()));
         }
 
-        if ( artifactNode.hasProperty( "size" ) )
-        {
-            artifact.setSize( artifactNode.getProperty( "size" ).getLong() );
+        if (artifactNode.hasProperty("size")) {
+            artifact.setSize(artifactNode.getProperty("size").getLong());
         }
 
-        Node cslistNode = getOrAddNodeByPath( artifactNode, "checksums" );
-        NodeIterator csNodeIt = cslistNode.getNodes( "*" );
+        Node cslistNode = getOrAddNodeByPath(artifactNode, "checksums");
+        NodeIterator csNodeIt = cslistNode.getNodes("*");
         while (csNodeIt.hasNext()) {
-            Node csNode = csNodeIt.nextNode( );
-            if (csNode.isNodeType( CHECKSUM_NODE_TYPE ))
-            {
-                addChecksum( artifact, csNode );
+            Node csNode = csNodeIt.nextNode();
+            if (csNode.isNodeType(CHECKSUM_NODE_TYPE)) {
+                addChecksum(artifact, csNode);
             }
         }
 
-        retrieveFacetProperties( artifact, artifactNode );
+        retrieveFacetProperties(artifact, artifactNode);
         return artifact;
     }
 
     private void addChecksum(ArtifactMetadata artifact, Node n) {
-        try
-        {
-            ChecksumAlgorithm alg = ChecksumAlgorithm.valueOf( n.getProperty( "type" ).getString() );
-            String value = n.getProperty( "value" ).getString( );
-            artifact.setChecksum( alg, value );
-        }
-        catch ( Throwable e )
-        {
-            log.error( "Could not set checksum from node {}", n );
+        try {
+            ChecksumAlgorithm alg = ChecksumAlgorithm.valueOf(n.getProperty("type").getString());
+            String value = n.getProperty("value").getString();
+            artifact.setChecksum(alg, value);
+        } catch (Throwable e) {
+            log.error("Could not set checksum from node {}", n);
         }
     }
 
-    private static String getPropertyString( Node node, String name )
-        throws RepositoryException
-    {
-        return node.hasProperty( name ) ? node.getProperty( name ).getString() : null;
+    private static String getPropertyString(Node node, String name)
+            throws RepositoryException {
+        return node.hasProperty(name) ? node.getProperty(name).getString() : null;
     }
 
-    private List<String> getNodeNames( Session jcrSession, String path, String nodeType )
-        throws MetadataResolutionException
-    {
+    private List<String> getNodeNames(Session jcrSession, String path, String nodeType)
+            throws MetadataResolutionException {
 
         List<String> names = new ArrayList<>();
 
-        try
-        {
+        try {
             Node root = jcrSession.getRootNode();
 
-            Node nodeAtPath = root.getNode( path );
+            Node nodeAtPath = root.getNode(path);
 
-            for ( Node node : JcrUtils.getChildNodes( nodeAtPath ) )
-            {
-                if ( node.isNodeType( nodeType ) )
-                {
-                    names.add( node.getName() );
+            for (Node node : JcrUtils.getChildNodes(nodeAtPath)) {
+                if (node.isNodeType(nodeType)) {
+                    names.add(node.getName());
                 }
             }
-        }
-        catch ( PathNotFoundException e )
-        {
+        } catch (PathNotFoundException e) {
             // ignore repo not found for now
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage(), e);
         }
 
         return names;
     }
 
-    private static String getRepositoryPath( String repositoryId )
-    {
+    private static String getRepositoryPath(String repositoryId) {
         return "repositories/" + repositoryId;
     }
 
-    private static String getRepositoryContentPath( String repositoryId )
-    {
-        return getRepositoryPath( repositoryId ) + "/content";
+    private static String getRepositoryContentPath(String repositoryId) {
+        return getRepositoryPath(repositoryId) + "/content";
     }
 
-    private static String getFacetPath( String repositoryId, String facetId )
-    {
-        return StringUtils.isEmpty( facetId ) ? getRepositoryPath( repositoryId ) + "/facets" :
-            getRepositoryPath( repositoryId ) + "/facets/" + facetId;
+    private static String getFacetPath(String repositoryId, String facetId) {
+        return StringUtils.isEmpty(facetId) ? getRepositoryPath(repositoryId) + "/facets" :
+                getRepositoryPath(repositoryId) + "/facets/" + facetId;
     }
 
-    private static String getNamespacePath( String repositoryId, String namespace )
-    {
-        return getRepositoryContentPath( repositoryId ) + "/" + namespace.replace( '.', '/' );
+    private static String getNamespacePath(String repositoryId, String namespace) {
+        return getRepositoryContentPath(repositoryId) + "/" + namespace.replace('.', '/');
     }
 
-    private static String getProjectPath( String repositoryId, String namespace, String projectId )
-    {
-        return getNamespacePath( repositoryId, namespace ) + "/" + projectId;
+    private static String getProjectPath(String repositoryId, String namespace, String projectId) {
+        return getNamespacePath(repositoryId, namespace) + "/" + projectId;
     }
 
-    private static String getProjectVersionPath( String repositoryId, String namespace, String projectId,
-                                                 String projectVersion )
-    {
-        return getProjectPath( repositoryId, namespace, projectId ) + "/" + projectVersion;
+    private static String getProjectVersionPath(String repositoryId, String namespace, String projectId,
+                                                String projectVersion) {
+        return getProjectPath(repositoryId, namespace, projectId) + "/" + projectVersion;
     }
 
-    private static String getArtifactPath( String repositoryId, String namespace, String projectId,
-                                           String projectVersion, String id )
-    {
-        return getProjectVersionPath( repositoryId, namespace, projectId, projectVersion ) + "/" + id;
+    private static String getArtifactPath(String repositoryId, String namespace, String projectId,
+                                          String projectVersion, String id) {
+        return getProjectVersionPath(repositoryId, namespace, projectId, projectVersion) + "/" + id;
     }
 
-    private Node getOrAddNodeByPath( Node baseNode, String name )
-        throws RepositoryException
-    {
-        return getOrAddNodeByPath( baseNode, name, null );
+    private Node getOrAddNodeByPath(Node baseNode, String name)
+            throws RepositoryException {
+        return getOrAddNodeByPath(baseNode, name, null);
     }
 
-    private Node getOrAddNodeByPath( Node baseNode, String name, String nodeType ) throws RepositoryException {
+    private Node getOrAddNodeByPath(Node baseNode, String name, String nodeType) throws RepositoryException {
         return getOrAddNodeByPath(baseNode, name, nodeType, false);
     }
 
-    private Node getOrAddNodeByPath( Node baseNode, String name, String nodeType, boolean primaryType )
-        throws RepositoryException
-    {
-        log.debug( "getOrAddNodeByPath " + baseNode + " " + name + " " + nodeType );
+    private Node getOrAddNodeByPath(Node baseNode, String name, String nodeType, boolean primaryType)
+            throws RepositoryException {
+        log.debug("getOrAddNodeByPath " + baseNode + " " + name + " " + nodeType);
         Node node = baseNode;
-        for ( String n : name.split( "/" ) )
-        {
-            if (nodeType!=null && primaryType) {
-                node = JcrUtils.getOrAddNode( node, n, nodeType );
+        for (String n : name.split("/")) {
+            if (nodeType != null && primaryType) {
+                node = JcrUtils.getOrAddNode(node, n, nodeType);
             } else {
-                node = JcrUtils.getOrAddNode( node, n);
-                if ( nodeType != null && !node.isNodeType( nodeType ))
-                {
-                    node.addMixin( nodeType );
+                node = JcrUtils.getOrAddNode(node, n);
+                if (nodeType != null && !node.isNodeType(nodeType)) {
+                    node.addMixin(nodeType);
                 }
             }
-            if (!node.hasProperty( "id" )) {
-                node.setProperty( "id", n );
+            if (!node.hasProperty("id")) {
+                node.setProperty("id", n);
             }
         }
         return node;
     }
 
-    private static String getFacetPath( String repositoryId, String facetId, String name )
-    {
-        return getFacetPath( repositoryId, facetId ) + "/" + name;
+    private static String getFacetPath(String repositoryId, String facetId, String name) {
+        return getFacetPath(repositoryId, facetId) + "/" + name;
     }
 
-    private Node getOrAddRepositoryNode( Session jcrSession, String repositoryId )
-        throws RepositoryException
-    {
-        log.debug( "getOrAddRepositoryNode " + repositoryId );
+    private Node getOrAddRepositoryNode(Session jcrSession, String repositoryId)
+            throws RepositoryException {
+        log.debug("getOrAddRepositoryNode " + repositoryId);
         Node root = jcrSession.getRootNode();
-        Node node = JcrUtils.getOrAddNode( root, "repositories" );
-        log.debug( "Repositories " + node );
-        node = JcrUtils.getOrAddNode( node, repositoryId, JcrConstants.NT_UNSTRUCTURED );
-        if (!node.isNodeType( org.apache.archiva.metadata.repository.jcr.JcrConstants.REPOSITORY_NODE_TYPE )) {
-            node.addMixin( org.apache.archiva.metadata.repository.jcr.JcrConstants.REPOSITORY_NODE_TYPE );
+        Node node = JcrUtils.getOrAddNode(root, "repositories");
+        log.debug("Repositories " + node);
+        node = JcrUtils.getOrAddNode(node, repositoryId, JcrConstants.NT_UNSTRUCTURED);
+        if (!node.isNodeType(org.apache.archiva.metadata.repository.jcr.JcrConstants.REPOSITORY_NODE_TYPE)) {
+            node.addMixin(org.apache.archiva.metadata.repository.jcr.JcrConstants.REPOSITORY_NODE_TYPE);
         }
-        if (!node.hasProperty( "id" )) {
-            node.setProperty( "id", repositoryId );
+        if (!node.hasProperty("id")) {
+            node.setProperty("id", repositoryId);
         }
         return node;
     }
 
-    private Node getOrAddRepositoryContentNode( Session jcrSession, String repositoryId )
-        throws RepositoryException
-    {
-        Node node = getOrAddRepositoryNode( jcrSession, repositoryId );
-        return JcrUtils.getOrAddNode( node, "content" );
+    private Node getOrAddRepositoryContentNode(Session jcrSession, String repositoryId)
+            throws RepositoryException {
+        Node node = getOrAddRepositoryNode(jcrSession, repositoryId);
+        return JcrUtils.getOrAddNode(node, "content");
     }
 
-    private Node getOrAddNamespaceNode( Session jcrSession, String repositoryId, String namespace )
-        throws RepositoryException
-    {
-        Node repo = getOrAddRepositoryContentNode( jcrSession, repositoryId );
-        return getOrAddNodeByPath( repo, namespace.replace( '.', '/' ), NAMESPACE_NODE_TYPE );
+    private Node getOrAddNamespaceNode(Session jcrSession, String repositoryId, String namespace)
+            throws RepositoryException {
+        Node repo = getOrAddRepositoryContentNode(jcrSession, repositoryId);
+        return getOrAddNodeByPath(repo, namespace.replace('.', '/'), NAMESPACE_NODE_TYPE);
     }
 
-    private Node getOrAddProjectNode( Session jcrSession, String repositoryId, String namespace, String projectId )
-        throws RepositoryException
-    {
-        Node namespaceNode = getOrAddNamespaceNode( jcrSession, repositoryId, namespace );
-        Node node = JcrUtils.getOrAddNode( namespaceNode, projectId );
-        if (!node.isNodeType( org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_NODE_TYPE ))
-        {
-            node.addMixin( org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_NODE_TYPE );
+    private Node getOrAddProjectNode(Session jcrSession, String repositoryId, String namespace, String projectId)
+            throws RepositoryException {
+        Node namespaceNode = getOrAddNamespaceNode(jcrSession, repositoryId, namespace);
+        Node node = JcrUtils.getOrAddNode(namespaceNode, projectId);
+        if (!node.isNodeType(org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_NODE_TYPE)) {
+            node.addMixin(org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_NODE_TYPE);
         }
-        if (!node.hasProperty( "id" ))
-        {
-            node.setProperty( "id", projectId );
+        if (!node.hasProperty("id")) {
+            node.setProperty("id", projectId);
         }
         return node;
     }
 
-    private Node getOrAddProjectVersionNode( Session jcrSession, String repositoryId, String namespace, String projectId,
-                                             String projectVersion )
-        throws RepositoryException
-    {
-        Node projectNode = getOrAddProjectNode( jcrSession, repositoryId, namespace, projectId );
-        log.debug( "Project node {}", projectNode );
-        Node projectVersionNode = JcrUtils.getOrAddNode( projectNode, projectVersion, JcrConstants.NT_UNSTRUCTURED);
-        if (!projectVersionNode.isNodeType( PROJECT_VERSION_NODE_TYPE ))
-        {
-            projectVersionNode.addMixin( PROJECT_VERSION_NODE_TYPE );
-        }
-        if (!projectVersionNode.hasProperty( "id" ))
-        {
-            projectVersionNode.setProperty( "id", projectVersion );
+    private Node getOrAddProjectVersionNode(Session jcrSession, String repositoryId, String namespace, String projectId,
+                                            String projectVersion)
+            throws RepositoryException {
+        Node projectNode = getOrAddProjectNode(jcrSession, repositoryId, namespace, projectId);
+        log.debug("Project node {}", projectNode);
+        Node projectVersionNode = JcrUtils.getOrAddNode(projectNode, projectVersion, PROJECT_VERSION_NODE_TYPE);
+        if (!projectVersionNode.hasProperty("id")) {
+            projectVersionNode.setProperty("id", projectVersion);
         }
 
-        log.debug( "Project version node {}", projectVersionNode );
+        log.debug("Project version node {}", projectVersionNode);
         return projectVersionNode;
     }
 
-    private Node getOrAddArtifactNode( Session jcrSession, String repositoryId, String namespace, String projectId, String projectVersion,
-                                       String id )
-        throws RepositoryException
-    {
-        Node versionNode = getOrAddProjectVersionNode( jcrSession, repositoryId, namespace, projectId, projectVersion );
-        Node node = JcrUtils.getOrAddNode( versionNode, id, ARTIFACT_NODE_TYPE);
-        if (!node.hasProperty( "id" )) {
-            node.setProperty( "id", id );
+    private Node getOrAddArtifactNode(Session jcrSession, String repositoryId, String namespace, String projectId, String projectVersion,
+                                      String id)
+            throws RepositoryException {
+        Node versionNode = getOrAddProjectVersionNode(jcrSession, repositoryId, namespace, projectId, projectVersion);
+        Node node = JcrUtils.getOrAddNode(versionNode, id, ARTIFACT_NODE_TYPE);
+        if (!node.hasProperty("id")) {
+            node.setProperty("id", id);
         }
         return node;
     }
 
-    private static Calendar createCalendar( ZonedDateTime time )
-    {
+    private Node findArtifactNode(Session jcrSession, String namespace, String projectId,
+                                  String projectVersion, String id) throws RepositoryException {
+
+
+        Node root = jcrSession.getRootNode();
+        Node node = JcrUtils.getOrAddNode(root, "repositories");
+        for (Node n : JcrUtils.getChildNodes(node)) {
+            String repositoryId = n.getName();
+            Node repo = getOrAddRepositoryContentNode(jcrSession, repositoryId);
+            Node nsNode = JcrUtils.getNodeIfExists(repo, StringUtils.replaceChars(namespace, '.', '/'));
+            if (nsNode!=null) {
+                Node projNode = JcrUtils.getNodeIfExists(nsNode, projectId);
+                if (projNode !=null ) {
+                    Node projVersionNode = JcrUtils.getNodeIfExists(projNode, projectVersion);
+                    if (projVersionNode != null) {
+                        return JcrUtils.getNodeIfExists(projVersionNode, id);
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private static Calendar createCalendar(ZonedDateTime time) {
         return GregorianCalendar.from(time);
     }
 
-    private String join( Collection<String> ids )
-    {
-        if ( ids != null && !ids.isEmpty() )
-        {
+    private String join(Collection<String> ids) {
+        if (ids != null && !ids.isEmpty()) {
             StringBuilder s = new StringBuilder();
-            for ( String id : ids )
-            {
-                s.append( id );
-                s.append( "," );
+            for (String id : ids) {
+                s.append(id);
+                s.append(",");
             }
-            return s.substring( 0, s.length() - 1 );
+            return s.substring(0, s.length() - 1);
         }
         return null;
     }
 
 
     @Override
-    public void populateStatistics( RepositorySession repositorySession, MetadataRepository repository, String repositoryId,
-                                    RepositoryStatistics repositoryStatistics )
-        throws MetadataRepositoryException
-    {
-        if ( !( repository instanceof JcrMetadataRepository ) )
-        {
+    public void populateStatistics(RepositorySession repositorySession, MetadataRepository repository, String repositoryId,
+                                   RepositoryStatistics repositoryStatistics)
+            throws MetadataRepositoryException {
+        if (!(repository instanceof JcrMetadataRepository)) {
             throw new MetadataRepositoryException(
-                "The statistics population is only possible for JcrMetdataRepository implementations" );
+                    "The statistics population is only possible for JcrMetdataRepository implementations");
         }
-        Session session = getSession( repositorySession );
+        Session session = getSession(repositorySession);
         // TODO: these may be best as running totals, maintained by observations on the properties in JCR
 
-        try
-        {
+        try {
             QueryManager queryManager = session.getWorkspace().getQueryManager();
 
             // TODO: Check, if this is still the case - Switched to Jackrabbit OAK with archiva 3.0
@@ -1969,166 +1690,134 @@ public class JcrMetadataRepository
 //            Query query = queryManager.createQuery( "SELECT size FROM [archiva:artifact] " + whereClause,
 //                                                    Query.JCR_SQL2 );
             String whereClause = "WHERE ISDESCENDANTNODE([/repositories/" + repositoryId + "/content])";
-            Query query = queryManager.createQuery( "SELECT type,size FROM ["+ARTIFACT_NODE_TYPE+"] " + whereClause, Query.JCR_SQL2 );
+            Query query = queryManager.createQuery("SELECT type,size FROM [" + ARTIFACT_NODE_TYPE + "] " + whereClause, Query.JCR_SQL2);
 
             QueryResult queryResult = query.execute();
 
             Map<String, Integer> totalByType = new HashMap<>();
             long totalSize = 0, totalArtifacts = 0;
-            for ( Row row : JcrUtils.getRows( queryResult ) )
-            {
+            for (Row row : JcrUtils.getRows(queryResult)) {
                 Node n = row.getNode();
-                log.debug( "Result node {}", n );
-                totalSize += row.getValue( "size" ).getLong();
+                log.debug("Result node {}", n);
+                totalSize += row.getValue("size").getLong();
 
                 String type;
-                if ( n.hasNode( MavenArtifactFacet.FACET_ID ) )
-                {
-                    Node facetNode = n.getNode( MavenArtifactFacet.FACET_ID );
-                    type = facetNode.getProperty( "type" ).getString();
-                }
-                else
-                {
+                if (n.hasNode(MavenArtifactFacet.FACET_ID)) {
+                    Node facetNode = n.getNode(MavenArtifactFacet.FACET_ID);
+                    type = facetNode.getProperty("type").getString();
+                } else {
                     type = "Other";
                 }
-                Integer prev = totalByType.get( type );
-                totalByType.put( type, prev != null ? prev + 1 : 1 );
+                Integer prev = totalByType.get(type);
+                totalByType.put(type, prev != null ? prev + 1 : 1);
 
                 totalArtifacts++;
             }
 
-            repositoryStatistics.setTotalArtifactCount( totalArtifacts );
-            repositoryStatistics.setTotalArtifactFileSize( totalSize );
-            for ( Map.Entry<String, Integer> entry : totalByType.entrySet() )
-            {
-                log.info( "Setting count for type: {} = {}", entry.getKey(), entry.getValue() );
-                repositoryStatistics.setTotalCountForType( entry.getKey(), entry.getValue() );
+            repositoryStatistics.setTotalArtifactCount(totalArtifacts);
+            repositoryStatistics.setTotalArtifactFileSize(totalSize);
+            for (Map.Entry<String, Integer> entry : totalByType.entrySet()) {
+                log.info("Setting count for type: {} = {}", entry.getKey(), entry.getValue());
+                repositoryStatistics.setTotalCountForType(entry.getKey(), entry.getValue());
             }
 
             // The query ordering is a trick to ensure that the size is correct, otherwise due to lazy init it will be -1
 //            query = queryManager.createQuery( "SELECT * FROM [archiva:project] " + whereClause, Query.JCR_SQL2 );
-            query = queryManager.createQuery( "SELECT * FROM [archiva:project] " + whereClause + " ORDER BY [jcr:score]",
-                                              Query.JCR_SQL2 );
-            repositoryStatistics.setTotalProjectCount( query.execute().getRows().getSize() );
+            query = queryManager.createQuery("SELECT * FROM [archiva:project] " + whereClause + " ORDER BY [jcr:score]",
+                    Query.JCR_SQL2);
+            repositoryStatistics.setTotalProjectCount(query.execute().getRows().getSize());
 
 //            query = queryManager.createQuery(
 //                "SELECT * FROM [archiva:namespace] " + whereClause + " AND namespace IS NOT NULL", Query.JCR_SQL2 );
             query = queryManager.createQuery(
-                "SELECT * FROM [archiva:namespace] " + whereClause + " AND namespace IS NOT NULL ORDER BY [jcr:score]",
-                Query.JCR_SQL2 );
-            repositoryStatistics.setTotalGroupCount( query.execute().getRows().getSize() );
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataRepositoryException( e.getMessage(), e );
+                    "SELECT * FROM [archiva:namespace] " + whereClause + " AND namespace IS NOT NULL ORDER BY [jcr:score]",
+                    Query.JCR_SQL2);
+            repositoryStatistics.setTotalGroupCount(query.execute().getRows().getSize());
+        } catch (RepositoryException e) {
+            throw new MetadataRepositoryException(e.getMessage(), e);
         }
     }
 
 
-    public Session login() throws RepositoryException
-    {
-        return repository.login(new SimpleCredentials( "admin", "admin".toCharArray() ) );
+    public Session login() throws RepositoryException {
+        return repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
     }
 
     private static boolean isArtifactNodeType(Node n) {
-        try
-        {
-            return n != null && n.isNodeType( ARTIFACT_NODE_TYPE );
-        }
-        catch ( RepositoryException e )
-        {
+        try {
+            return n != null && n.isNodeType(ARTIFACT_NODE_TYPE);
+        } catch (RepositoryException e) {
             return false;
         }
     }
 
     private Optional<ArtifactMetadata> getArtifactOptional(final String repositoryId, final Node n) {
-        try
-        {
-            return Optional.ofNullable( getArtifactFromNode( repositoryId, n ) );
-        }
-        catch ( RepositoryException e )
-        {
-            return Optional.empty( );
+        try {
+            return Optional.ofNullable(getArtifactFromNode(repositoryId, n));
+        } catch (RepositoryException e) {
+            return Optional.empty();
         }
     }
 
     private Optional<ArtifactMetadata> getArtifactOptional(final String repositoryId, final Row row) {
-        try
-        {
-            return Optional.of( getArtifactFromNode( repositoryId, row.getNode( "artifact" ) ) );
-        }
-        catch ( RepositoryException e )
-        {
-            return Optional.empty( );
+        try {
+            return Optional.of(getArtifactFromNode(repositoryId, row.getNode("artifact")));
+        } catch (RepositoryException e) {
+            return Optional.empty();
         }
     }
 
     @Override
-    public Stream<ArtifactMetadata> getArtifactStream( final RepositorySession session, final String repositoryId,
-                                                       final String namespace, final String projectId, final String projectVersion,
-                                                       final QueryParameter queryParameter ) throws MetadataResolutionException
-    {
+    public Stream<ArtifactMetadata> getArtifactStream(final RepositorySession session, final String repositoryId,
+                                                      final String namespace, final String projectId, final String projectVersion,
+                                                      final QueryParameter queryParameter) throws MetadataResolutionException {
         final Session jcrSession;
-        try
-        {
-            jcrSession = getSession( session );
-        }
-        catch ( MetadataRepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage( ) );
+        try {
+            jcrSession = getSession(session);
+        } catch (MetadataRepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage());
         }
 
-        try
-        {
+        try {
             Node root = jcrSession.getRootNode();
-            String path = getProjectVersionPath( repositoryId, namespace, projectId, projectVersion );
-
-            if ( root.hasNode( path ) )
-            {
-                Node node = root.getNode( path );
-                return StreamSupport.stream( JcrUtils.getChildNodes( node ).spliterator( ), false ).filter(JcrMetadataRepository::isArtifactNodeType)
-                    .map( n -> getArtifactOptional( repositoryId, n ) )
-                .map( Optional::get ).skip( queryParameter.getOffset( ) ).limit( queryParameter.getLimit( ) );
+            String path = getProjectVersionPath(repositoryId, namespace, projectId, projectVersion);
+
+            if (root.hasNode(path)) {
+                Node node = root.getNode(path);
+                return StreamSupport.stream(JcrUtils.getChildNodes(node).spliterator(), false).filter(JcrMetadataRepository::isArtifactNodeType)
+                        .map(n -> getArtifactOptional(repositoryId, n))
+                        .map(Optional::get).skip(queryParameter.getOffset()).limit(queryParameter.getLimit());
             } else {
-                return Stream.empty( );
+                return Stream.empty();
             }
-        }
-        catch ( RepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage(), e );
+        } catch (RepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage(), e);
         }
     }
 
     @Override
-    public Stream<ArtifactMetadata> getArtifactStream( final RepositorySession session, final String repositoryId,
-                                                       final QueryParameter queryParameter ) throws MetadataResolutionException
-    {
+    public Stream<ArtifactMetadata> getArtifactStream(final RepositorySession session, final String repositoryId,
+                                                      final QueryParameter queryParameter) throws MetadataResolutionException {
         final Session jcrSession;
-        try
-        {
-            jcrSession = getSession( session );
-        }
-        catch ( MetadataRepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage( ), e );
+        try {
+            jcrSession = getSession(session);
+        } catch (MetadataRepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage(), e);
         }
         List<ArtifactMetadata> artifacts;
 
-        String q = getArtifactQuery( repositoryId ).toString();
+        String q = getArtifactQuery(repositoryId).toString();
 
-        try
-        {
-            Query query = jcrSession.getWorkspace().getQueryManager().createQuery( q, Query.JCR_SQL2 );
+        try {
+            Query query = jcrSession.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2);
             QueryResult result = query.execute();
 
-            return StreamSupport.stream( createResultSpliterator( result, getArtifactFromRowFunc( repositoryId )), false )
-                .filter(Optional::isPresent).map(Optional::get)
-                .skip( queryParameter.getOffset( ) ).limit( queryParameter.getLimit( ) );
+            return StreamSupport.stream(createResultSpliterator(result, getArtifactFromRowFunc(repositoryId)), false)
+                    .filter(Optional::isPresent).map(Optional::get)
+                    .skip(queryParameter.getOffset()).limit(queryParameter.getLimit());
 
-        }
-        catch ( RepositoryException | MetadataRepositoryException e )
-        {
-            throw new MetadataResolutionException( e.getMessage(), e );
+        } catch (RepositoryException | MetadataRepositoryException e) {
+            throw new MetadataResolutionException(e.getMessage(), e);
         }
 
     }
diff --git a/archiva-modules/plugins/metadata-store-jcr/src/main/resources/org/apache/archiva/metadata/repository/jcr/jcr-schema.cnd b/archiva-modules/plugins/metadata-store-jcr/src/main/resources/org/apache/archiva/metadata/repository/jcr/jcr-schema.cnd
index bf753fc..6c267ab 100644
--- a/archiva-modules/plugins/metadata-store-jcr/src/main/resources/org/apache/archiva/metadata/repository/jcr/jcr-schema.cnd
+++ b/archiva-modules/plugins/metadata-store-jcr/src/main/resources/org/apache/archiva/metadata/repository/jcr/jcr-schema.cnd
@@ -59,31 +59,33 @@
  - org.name (string)
  - org.url (uri)
 
-[archiva:meta_license] > archiva:base mixin
+[archiva:license] > archiva:base
  - index (long)
- - license.name (string)
- - license.url (uri)
+ - name (string)
+ - url (uri)
 
-[archiva:meta_mailinglist] > archiva:base
+[archiva:mailinglist] > archiva:base
  - index (long)
  - name (string)
  - archive (string)
  - post (string)
  - unsubscribe (string)
  - subscribe (string)
- - otherArchives (string) multiple
+ - otherArchives (string)
 
 [archiva:dependency] > archiva:base
- - groupId (string)
- - artifactId (string)
+ - namespace (string)
+ - projectId (string)
  - version (string)
+ - artifactId (string)
  - type (string)
  - classifier (string)
  - scope (string)
  - systemPath (string)
  - optional (boolean)
+ - link (path)
 
-[archiva:dependencies] mixin
+[archiva:dependencies] > nt:hierarchyNode
  + * (archiva:dependency)
 
 [archiva:checksums] > nt:hierarchyNode
@@ -94,15 +96,22 @@
  - type (string)
  - value (string)
 
-[archiva:projectVersion] > archiva:base, archiva:meta_scm, archiva:meta_ci, archiva:meta_issue, archiva:meta_organization mixin
+[archiva:mailinglists] > nt:hierarchyNode
+ + * (archiva:mailinglist)
+
+[archiva:licenses] > nt:hierarchyNode
+ + * (archiva:license)
+
+
+[archiva:projectVersion] > archiva:base, archiva:meta_scm, archiva:meta_ci, archiva:meta_issue, archiva:meta_organization
  - name (string)
  - description (string)
  - url (uri)
  - incomplete (boolean)
  + * (archiva:artifact)
- + * (archiva:meta_license)
- + * (archiva:meta_mailinglist)
- + * (archiva:dependencies)
+ + licenses (archiva:licenses)
+ + mailinglists (archiva:mailinglists)
+ + dependencies (archiva:dependencies)
  + * (archiva:facet)