You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by hb...@apache.org on 2017/01/15 19:23:42 UTC

[08/53] [abbrv] [partial] maven-resolver git commit: [MNG-6007] renamed Aether to Maven Artifact Resolver

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/java/org/eclipse/aether/util/version/UnionVersionRangeTest.java
----------------------------------------------------------------------
diff --git a/aether-util/src/test/java/org/eclipse/aether/util/version/UnionVersionRangeTest.java b/aether-util/src/test/java/org/eclipse/aether/util/version/UnionVersionRangeTest.java
deleted file mode 100644
index 570b6b7..0000000
--- a/aether-util/src/test/java/org/eclipse/aether/util/version/UnionVersionRangeTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package org.eclipse.aether.util.version;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *  http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import static org.junit.Assert.*;
-
-import java.util.Collections;
-
-import org.eclipse.aether.version.InvalidVersionSpecificationException;
-import org.eclipse.aether.version.VersionRange;
-import org.junit.Test;
-
-public class UnionVersionRangeTest
-{
-
-    private VersionRange newRange( String range )
-    {
-        try
-        {
-            return new GenericVersionScheme().parseVersionRange( range );
-        }
-        catch ( InvalidVersionSpecificationException e )
-        {
-            throw new IllegalArgumentException( e );
-        }
-    }
-
-    private void assertBound( String version, boolean inclusive, VersionRange.Bound bound )
-    {
-        if ( version == null )
-        {
-            assertNull( bound );
-        }
-        else
-        {
-            assertNotNull( bound );
-            assertNotNull( bound.getVersion() );
-            assertEquals( inclusive, bound.isInclusive() );
-            try
-            {
-                assertEquals( new GenericVersionScheme().parseVersion( version ), bound.getVersion() );
-            }
-            catch ( InvalidVersionSpecificationException e )
-            {
-                throw new IllegalArgumentException( e );
-            }
-        }
-    }
-
-    @Test
-    public void testGetLowerBound()
-    {
-        VersionRange range = UnionVersionRange.from( Collections.<VersionRange> emptySet() );
-        assertBound( null, false, range.getLowerBound() );
-
-        range = UnionVersionRange.from( newRange( "[1,2]" ), newRange( "[3,4]" ) );
-        assertBound( "1", true, range.getLowerBound() );
-
-        range = UnionVersionRange.from( newRange( "[1,2]" ), newRange( "(,4]" ) );
-        assertBound( null, false, range.getLowerBound() );
-
-        range = UnionVersionRange.from( newRange( "[1,2]" ), newRange( "(1,4]" ) );
-        assertBound( "1", true, range.getLowerBound() );
-
-        range = UnionVersionRange.from( newRange( "[1,2]" ), newRange( "(0,4]" ) );
-        assertBound( "0", false, range.getLowerBound() );
-    }
-
-    @Test
-    public void testGetUpperBound()
-    {
-        VersionRange range = UnionVersionRange.from( Collections.<VersionRange> emptySet() );
-        assertBound( null, false, range.getUpperBound() );
-
-        range = UnionVersionRange.from( newRange( "[1,2]" ), newRange( "[3,4]" ) );
-        assertBound( "4", true, range.getUpperBound() );
-
-        range = UnionVersionRange.from( newRange( "[1,2]" ), newRange( "[3,)" ) );
-        assertBound( null, false, range.getUpperBound() );
-
-        range = UnionVersionRange.from( newRange( "[1,2]" ), newRange( "[1,2)" ) );
-        assertBound( "2", true, range.getUpperBound() );
-
-        range = UnionVersionRange.from( newRange( "[1,2]" ), newRange( "[1,3)" ) );
-        assertBound( "3", false, range.getUpperBound() );
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/conflict-id-sorter/cycle.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/conflict-id-sorter/cycle.txt b/aether-util/src/test/resources/transformer/conflict-id-sorter/cycle.txt
deleted file mode 100644
index 1c200b9..0000000
--- a/aether-util/src/test/resources/transformer/conflict-id-sorter/cycle.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-(null)
-+- gid:aid:ver
-|  \- gid2:aid:ver
-\- gid2:aid:ver
-   \- gid:aid:ver

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/conflict-id-sorter/cycles.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/conflict-id-sorter/cycles.txt b/aether-util/src/test/resources/transformer/conflict-id-sorter/cycles.txt
deleted file mode 100644
index 714069e..0000000
--- a/aether-util/src/test/resources/transformer/conflict-id-sorter/cycles.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-(null)
-+- gid1:aid:ver
-|  \- gid2:aid:ver
-|     \- gid:aid:ver
-+- gid2:aid:ver
-|  \- gid1:aid:ver
-+- gid1:aid:ver
-|  \- gid3:aid:ver
-+- gid3:aid:ver
-|  \- gid1:aid:ver
-+- gid2:aid:ver
-|  \- gid3:aid:ver
-\- gid3:aid:ver
-   \- gid2:aid:ver

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/conflict-id-sorter/no-conflicts.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/conflict-id-sorter/no-conflicts.txt b/aether-util/src/test/resources/transformer/conflict-id-sorter/no-conflicts.txt
deleted file mode 100644
index c4d1c89..0000000
--- a/aether-util/src/test/resources/transformer/conflict-id-sorter/no-conflicts.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-(null)
-+- gid:aid:ver
-|  \- gid2:aid:ver
-\- gid3:aid:ver
-   \- gid4:aid:ver

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/conflict-id-sorter/simple.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/conflict-id-sorter/simple.txt b/aether-util/src/test/resources/transformer/conflict-id-sorter/simple.txt
deleted file mode 100644
index 01ce915..0000000
--- a/aether-util/src/test/resources/transformer/conflict-id-sorter/simple.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-(null)
-+- gid:aid:ver
-|  \- gid:aid2:ver
-\- gid2:aid:ver
-   \- gid:aid:ver

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/conflict-marker/relocation1.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/conflict-marker/relocation1.txt b/aether-util/src/test/resources/transformer/conflict-marker/relocation1.txt
deleted file mode 100644
index 518f706..0000000
--- a/aether-util/src/test/resources/transformer/conflict-marker/relocation1.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-(null)
-+- test:a:1
-\- test:a:1 relocations=test:reloc:1

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/conflict-marker/relocation2.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/conflict-marker/relocation2.txt b/aether-util/src/test/resources/transformer/conflict-marker/relocation2.txt
deleted file mode 100644
index 729748d..0000000
--- a/aether-util/src/test/resources/transformer/conflict-marker/relocation2.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-(null)
-+- test:a:1 relocations=test:reloc:1
-\- test:a:1

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/conflict-marker/relocation3.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/conflict-marker/relocation3.txt b/aether-util/src/test/resources/transformer/conflict-marker/relocation3.txt
deleted file mode 100644
index 8b96d18..0000000
--- a/aether-util/src/test/resources/transformer/conflict-marker/relocation3.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-(null)
-+- test:a:1
-+- test:b:1
-\- test:c:1 relocations=test:a:1,test:b:1

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/conflict-marker/simple.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/conflict-marker/simple.txt b/aether-util/src/test/resources/transformer/conflict-marker/simple.txt
deleted file mode 100644
index 2f94bb4..0000000
--- a/aether-util/src/test/resources/transformer/conflict-marker/simple.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-(null)
-+- test:a:1
-\- test:b:1

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/optionality-selector/conflict-direct-dep.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/optionality-selector/conflict-direct-dep.txt b/aether-util/src/test/resources/transformer/optionality-selector/conflict-direct-dep.txt
deleted file mode 100644
index 13ac2aa..0000000
--- a/aether-util/src/test/resources/transformer/optionality-selector/conflict-direct-dep.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-(null)
-+- test:a:1
-|  \- test:x:1
-\- test:x:1 optional

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/optionality-selector/conflict.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/optionality-selector/conflict.txt b/aether-util/src/test/resources/transformer/optionality-selector/conflict.txt
deleted file mode 100644
index ffab99b..0000000
--- a/aether-util/src/test/resources/transformer/optionality-selector/conflict.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-(null)
-+- test:a:1 optional
-|  \- test:x:1
-\- test:b:1
-   \- test:x:1

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/optionality-selector/derive.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/optionality-selector/derive.txt b/aether-util/src/test/resources/transformer/optionality-selector/derive.txt
deleted file mode 100644
index 37a394a..0000000
--- a/aether-util/src/test/resources/transformer/optionality-selector/derive.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-(null)
-+- test:a:1 optional
-|  \- test:b:1
-\- test:c:1 !optional
-   \- test:d:1

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/scope-calculator/conflict-and-inheritance.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/scope-calculator/conflict-and-inheritance.txt b/aether-util/src/test/resources/transformer/scope-calculator/conflict-and-inheritance.txt
deleted file mode 100644
index 558049c..0000000
--- a/aether-util/src/test/resources/transformer/scope-calculator/conflict-and-inheritance.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-# Another scenario to check that scope inheritance considers the effective scopes of parent nodes as determined during
-# scope conflict resolution. In this example, gid:x:1 should end up in compile scope (and not runtime) because its
-# parent gid:c:2 will be promoted to compile scope due to a conflict with gid:c:1.
-
-gid:root:1
-+- gid:a:1 compile
-|  \- gid:c:2 runtime
-|     \- gid:x:1 compile
-\- gid:b:1 compile
-   \- gid:c:1 compile

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/scope-calculator/conflicting-direct-nodes.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/scope-calculator/conflicting-direct-nodes.txt b/aether-util/src/test/resources/transformer/scope-calculator/conflicting-direct-nodes.txt
deleted file mode 100644
index 3330251..0000000
--- a/aether-util/src/test/resources/transformer/scope-calculator/conflicting-direct-nodes.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-(null)
-+- gid:aid:ver %s
-\- gid:aid:ver %s

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/scope-calculator/cycle-a.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/scope-calculator/cycle-a.txt b/aether-util/src/test/resources/transformer/scope-calculator/cycle-a.txt
deleted file mode 100644
index df2d828..0000000
--- a/aether-util/src/test/resources/transformer/scope-calculator/cycle-a.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Checks for graceful handling of cycles in the graph of conflict groups. Below, the group {a:1, a:2} depends on
-# {b:1, b:2} and vice versa. Additionally, each group contains a direct dependency.
-
-gid:root:1
-+- gid:a:1 compile
-|  \- gid:b:1 compile
-\- gid:b:2 runtime
-   \- gid:a:2 runtime

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/scope-calculator/cycle-b.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/scope-calculator/cycle-b.txt b/aether-util/src/test/resources/transformer/scope-calculator/cycle-b.txt
deleted file mode 100644
index 5fe084a..0000000
--- a/aether-util/src/test/resources/transformer/scope-calculator/cycle-b.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# Variation of cycle-a where the order of direct dependencies has been changed.
-
-gid:root:1
-+- gid:b:2 runtime
-|  \- gid:a:2 runtime
-\- gid:a:1 compile
-   \- gid:b:1 compile

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/scope-calculator/cycle-c.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/scope-calculator/cycle-c.txt b/aether-util/src/test/resources/transformer/scope-calculator/cycle-c.txt
deleted file mode 100644
index d3495b2..0000000
--- a/aether-util/src/test/resources/transformer/scope-calculator/cycle-c.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-# Checks for graceful handling of cycles in the graph of conflict groups. Below, the group {a:1} depends on
-# {b:1} and vice versa. The conflicting groups consist entirely of non-direct dependencies.
-
-gid:root:1
-+- gid:x:1 runtime
-|  \- gid:a:1 compile
-|     \- gid:b:1 compile
-\- gid:y:1 runtime
-   \- gid:b:1 compile
-      \- gid:a:1 compile

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/scope-calculator/cycle-d.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/scope-calculator/cycle-d.txt b/aether-util/src/test/resources/transformer/scope-calculator/cycle-d.txt
deleted file mode 100644
index c3a6824..0000000
--- a/aether-util/src/test/resources/transformer/scope-calculator/cycle-d.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# Checks for graceful handling of cycles in the graph of dependency nodes.
-
-gid:root:1
-\- gid:a:1 compile
-   \- gid:b:1 compile        (b)
-      \- gid:a:1 runtime
-         \- ^b

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/scope-calculator/direct-nodes-winning.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/scope-calculator/direct-nodes-winning.txt b/aether-util/src/test/resources/transformer/scope-calculator/direct-nodes-winning.txt
deleted file mode 100644
index 67edf3d..0000000
--- a/aether-util/src/test/resources/transformer/scope-calculator/direct-nodes-winning.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-(null)
-+- gid:aid:ver %s
-+- gid:aid2:ver
-|  \- gid:aid:ver provided
-+- gid:aid3:ver
-|  \- gid:aid:ver runtime
-+- gid:aid4:ver
-|  \- gid:aid:ver test
-\- gid:aid5:ver
-   \- gid:aid:ver compile
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/scope-calculator/direct-with-conflict-and-inheritance.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/scope-calculator/direct-with-conflict-and-inheritance.txt b/aether-util/src/test/resources/transformer/scope-calculator/direct-with-conflict-and-inheritance.txt
deleted file mode 100644
index c883214..0000000
--- a/aether-util/src/test/resources/transformer/scope-calculator/direct-with-conflict-and-inheritance.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-# When a direct dependency scope conflicts with a transitive dependency scope, the direct dependency scope always wins.
-# When the scope of the transitive dependency is updated, this update needs to be considered by scope inheritance.
-# In the graph below gid:a:1 has a conflict, after its resolution to test scope, gid:x:1 should end up in
-# test scope as well, everywhere in the graph.
-
-gid:root:1
-+- gid:a:1 test
-|  \- gid:x:1 compile
-\- gid:b:1 compile
-   \- gid:a:1 compile
-      \- gid:x:1 compile

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/scope-calculator/dueling-scopes.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/scope-calculator/dueling-scopes.txt b/aether-util/src/test/resources/transformer/scope-calculator/dueling-scopes.txt
deleted file mode 100644
index d2ae8e6..0000000
--- a/aether-util/src/test/resources/transformer/scope-calculator/dueling-scopes.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# pattern to test scope mediation in conflict groups
-
-(null)
-+- gid:aid2:ver
-|  \- gid:aid:ver %s
-\- gid:aid3:ver
-   \- gid:aid:ver %s

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/scope-calculator/inheritance.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/scope-calculator/inheritance.txt b/aether-util/src/test/resources/transformer/scope-calculator/inheritance.txt
deleted file mode 100644
index 3b832e9..0000000
--- a/aether-util/src/test/resources/transformer/scope-calculator/inheritance.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-root:a:ver
-\- gid:b:ver %s
-   \- gid:c:ver %s

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/scope-calculator/multiple-inheritance.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/scope-calculator/multiple-inheritance.txt b/aether-util/src/test/resources/transformer/scope-calculator/multiple-inheritance.txt
deleted file mode 100644
index d545ed6..0000000
--- a/aether-util/src/test/resources/transformer/scope-calculator/multiple-inheritance.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-(null)
-+- gid:aid:ver %s
-|  \- gid2:aid:ver compile   (1)
-\- gid3:aid:ver %s
-   \- ^1

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/scope-calculator/system-1.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/scope-calculator/system-1.txt b/aether-util/src/test/resources/transformer/scope-calculator/system-1.txt
deleted file mode 100644
index 61d8659..0000000
--- a/aether-util/src/test/resources/transformer/scope-calculator/system-1.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-gid:aid:1
-+- gid:aid2:2 compile
-\- gid:aid2:3 system

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/scope-calculator/system-2.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/scope-calculator/system-2.txt b/aether-util/src/test/resources/transformer/scope-calculator/system-2.txt
deleted file mode 100644
index 04a5d59..0000000
--- a/aether-util/src/test/resources/transformer/scope-calculator/system-2.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-gid:aid:1
-+- gid:aid2:2 system
-\- gid:aid2:3 compile

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/conflict-id-cycle.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/conflict-id-cycle.txt b/aether-util/src/test/resources/transformer/version-resolver/conflict-id-cycle.txt
deleted file mode 100644
index 57c5d56..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/conflict-id-cycle.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# a graph which itself is acyclic but its conflict ids are cyclic (a <-> b)
-
-test:root:1
-+- test:a:1
-|  \- test:b:1
-\- test:b:2
-   \- test:a:2

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/cycle.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/cycle.txt b/aether-util/src/test/resources/transformer/version-resolver/cycle.txt
deleted file mode 100644
index 35c1c6a..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/cycle.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-cycle:root:1
-+- cycle:a:1
-|  \- cycle:b:1                   (b)
-|     \- cycle:c:1
-|        \- cycle:a:1             (a)
-|           \- ^b
-\- cycle:c:1
-   \- ^a

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/dead-conflict-group.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/dead-conflict-group.txt b/aether-util/src/test/resources/transformer/version-resolver/dead-conflict-group.txt
deleted file mode 100644
index cb49d9c..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/dead-conflict-group.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-test:root:1
-+- test:a:1
-|  \- test:b:1
-|     \- test:c:1     # conflict group c will completely vanish from resolved tree
-\- test:b:2

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/loop.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/loop.txt b/aether-util/src/test/resources/transformer/version-resolver/loop.txt
deleted file mode 100644
index 2b50f09..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/loop.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-gid:a:1
-\- gid:a:1

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/nearest-underneath-loser-a.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/nearest-underneath-loser-a.txt b/aether-util/src/test/resources/transformer/version-resolver/nearest-underneath-loser-a.txt
deleted file mode 100644
index c566caf..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/nearest-underneath-loser-a.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-test:root:1
-+- test:a:1
-|  \- test:b:1           # will be removed in favor of test:b:2
-|     \- test:j:1        # nearest version of j in dirty tree
-+- test:c:1
-|  \- test:d:1
-|     \- test:e:1
-|        \- test:j:1
-\- test:b:2

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/nearest-underneath-loser-b.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/nearest-underneath-loser-b.txt b/aether-util/src/test/resources/transformer/version-resolver/nearest-underneath-loser-b.txt
deleted file mode 100644
index 07867cb..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/nearest-underneath-loser-b.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-test:root:1
-+- test:a:1
-|  \- test:b:1           # will be removed in favor of test:b:2
-|     \- test:j:1        # nearest version of j in dirty tree
-+- test:c:1
-|  \- test:d:1
-|     \- test:e:1
-|        \- test:j:2
-\- test:b:2

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/overlapping-cycles.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/overlapping-cycles.txt b/aether-util/src/test/resources/transformer/version-resolver/overlapping-cycles.txt
deleted file mode 100644
index fa9e5aa..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/overlapping-cycles.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-cycle:root:1
-+- cycle:a:1                 (a)
-|  \- cycle:b:1
-|     \- cycle:c:1
-|        \- ^a
-\- cycle:b:1                 (b)
-   \- cycle:c:1
-      \- ^b

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/range-backtracking.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/range-backtracking.txt b/aether-util/src/test/resources/transformer/version-resolver/range-backtracking.txt
deleted file mode 100644
index 6634e7f..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/range-backtracking.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-(null)
-+- test:x:1
-+- test:a:1
-|  \- test:b:1
-|     \- test:x:3
-+- test:c:1
-|  \- test:x:2
-\- test:d:1
-   \- test:e:1
-      \- test:x:2[2,)   # forces rejection of x:1, should fallback to nearest and not first-seen, i.e. x:2 and not x:3

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/ranges.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/ranges.txt b/aether-util/src/test/resources/transformer/version-resolver/ranges.txt
deleted file mode 100644
index 9acf341..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/ranges.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-(null)
-+- test:b:1
-|  \- test:a:2[2]
-\- test:c:1
-   +- test:a:1[1,3]
-   +- test:a:2[1,3]
-   \- test:a:3[1,3]

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/scope-vs-version.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/scope-vs-version.txt b/aether-util/src/test/resources/transformer/version-resolver/scope-vs-version.txt
deleted file mode 100644
index 6c79cfe..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/scope-vs-version.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-# This highlights a design flaw in the previous separation of JavaEffectiveScopeCalculator and NearestVersionConflictResolver:
-# scope conflicts can't be properly determined and resolved until ancestor dependencies got their version conflicts resolved.
-# Otherwise, dependencies can get promoted to a scope due to a scope conflict which actually no longer arises after conflicting
-# versions got removed. In the dirty graph below, the effective scope of test:y should be "test" and not "compile" (as suggested
-# by its test:x parent).
-
-test:root:1
-+- test:a:1 compile
-|  +- test:x:1 compile             # (a)
-+- test:b:1 test
-|  +- test:y:1 compile
-+- test:c:1 test
-   +- test:x:1 compile             # conflicts with (a), hence leaving scope as "compile"
-      +- test:y:1 compile          # since our parent gets removed in favor of (a), no need to promote y into scope "compile"

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/sibling-versions.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/sibling-versions.txt b/aether-util/src/test/resources/transformer/version-resolver/sibling-versions.txt
deleted file mode 100644
index 5d50302..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/sibling-versions.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# multiple versions of the same GA beneath the same parent as seen after expansion of version ranges
-# versions neither in ascending nor descending order
-
-test:root:1
-+- test:a:1
-+- test:a:3
-\- test:a:2

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/soft-vs-range.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/soft-vs-range.txt b/aether-util/src/test/resources/transformer/version-resolver/soft-vs-range.txt
deleted file mode 100644
index d3b10e9..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/soft-vs-range.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-test:root:1
-+- test:a:1
-|  \- test:c:2     # nearest occurrence of c but doesn't match range given below
-\- test:b:1
-   \- test:c:1[1]

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/unsolvable-with-cycle.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/unsolvable-with-cycle.txt b/aether-util/src/test/resources/transformer/version-resolver/unsolvable-with-cycle.txt
deleted file mode 100644
index 153f030..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/unsolvable-with-cycle.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-# Conflict id "a" will be resolved before "x" such that the cycle formed by "x" is still in place when processing "a".
-# So in order to report the conflicting paths to "a" the code better supports cyclic graphs. 
-
-cycle:root:1
-+- cycle:x:1       (x)
-|  \- ^x
-+- cycle:a:1[1]
-\- cycle:b:1
-   \- cycle:a:2[2]
-      \- cycle:x:1

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/unsolvable.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/unsolvable.txt b/aether-util/src/test/resources/transformer/version-resolver/unsolvable.txt
deleted file mode 100644
index bbc260e..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/unsolvable.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-(null)
-+- test:b:1
-|  \- test:a:1[1]
-\- test:c:1
-   \- test:a:2[2]

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/transformer/version-resolver/verbose.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/transformer/version-resolver/verbose.txt b/aether-util/src/test/resources/transformer/version-resolver/verbose.txt
deleted file mode 100644
index 4bb3880..0000000
--- a/aether-util/src/test/resources/transformer/version-resolver/verbose.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-test:root:1
-+- test:a:1 test
-|  +- test:x:1 compile
-|  \- test:x:2 compile
-\- test:b:1 test
-   +- test:x:1 compile
-      \- test:z:1 compile
-   \- test:x:2 compile

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/visitor/filtering/parents.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/visitor/filtering/parents.txt b/aether-util/src/test/resources/visitor/filtering/parents.txt
deleted file mode 100644
index 9a93ca2..0000000
--- a/aether-util/src/test/resources/visitor/filtering/parents.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-gid:a:1
-+- gid:b:1
-|  \- gid:c:1
-|     \- gid:d:1
-\- gid:e:1
-   \- gid:f:1

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/visitor/ordered-list/cycles.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/visitor/ordered-list/cycles.txt b/aether-util/src/test/resources/visitor/ordered-list/cycles.txt
deleted file mode 100644
index 8de373c..0000000
--- a/aether-util/src/test/resources/visitor/ordered-list/cycles.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-gid:a:1
-+- gid:b:1 (1)
-|  \- gid:c:1
-|     \- ^1
-\- gid:d:1
-   +- ^1
-   \- gid:e:1

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/visitor/ordered-list/simple.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/visitor/ordered-list/simple.txt b/aether-util/src/test/resources/visitor/ordered-list/simple.txt
deleted file mode 100644
index 094d2d3..0000000
--- a/aether-util/src/test/resources/visitor/ordered-list/simple.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-gid:a:1
-+- gid:b:1
-|  \- gid:c:1
-\- gid:d:1
-   \- gid:e:1

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/visitor/path-recorder/cycle.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/visitor/path-recorder/cycle.txt b/aether-util/src/test/resources/visitor/path-recorder/cycle.txt
deleted file mode 100644
index 9a48240..0000000
--- a/aether-util/src/test/resources/visitor/path-recorder/cycle.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-gid:a:1 (a)
-+- gid:b:1 (b)
-|  \- match:x:1
-\- match:x:2 (x)
-   +- ^a
-   +- ^b
-   \- ^x

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/visitor/path-recorder/nested.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/visitor/path-recorder/nested.txt b/aether-util/src/test/resources/visitor/path-recorder/nested.txt
deleted file mode 100644
index 67742f8..0000000
--- a/aether-util/src/test/resources/visitor/path-recorder/nested.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-match:x:1
-+- gid:a:1
-|  \- match:y:2
-\- match:y:2

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/visitor/path-recorder/parents.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/visitor/path-recorder/parents.txt b/aether-util/src/test/resources/visitor/path-recorder/parents.txt
deleted file mode 100644
index 9a93ca2..0000000
--- a/aether-util/src/test/resources/visitor/path-recorder/parents.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-gid:a:1
-+- gid:b:1
-|  \- gid:c:1
-|     \- gid:d:1
-\- gid:e:1
-   \- gid:f:1

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/visitor/path-recorder/simple.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/visitor/path-recorder/simple.txt b/aether-util/src/test/resources/visitor/path-recorder/simple.txt
deleted file mode 100644
index 8f3c6a1..0000000
--- a/aether-util/src/test/resources/visitor/path-recorder/simple.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-gid:a:1
-+- gid:b:1
-|  \- match:x:1
-\- match:x:2

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/aether-util/src/test/resources/visitor/tree/cycles.txt
----------------------------------------------------------------------
diff --git a/aether-util/src/test/resources/visitor/tree/cycles.txt b/aether-util/src/test/resources/visitor/tree/cycles.txt
deleted file mode 100644
index f8d7abc..0000000
--- a/aether-util/src/test/resources/visitor/tree/cycles.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-gid:a:1
-+- gid:b:1 (1)
-|  \- gid:c:1
-|     \- ^1
-\- gid:d:1
-   \- ^1

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/pom.xml
----------------------------------------------------------------------
diff --git a/maven-resolver-api/pom.xml b/maven-resolver-api/pom.xml
new file mode 100644
index 0000000..307f21c
--- /dev/null
+++ b/maven-resolver-api/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.maven.resolver</groupId>
+    <artifactId>maven-resolver</artifactId>
+    <version>1.0.3-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>maven-resolver-api</artifactId>
+
+  <name>Maven Artifact Resolver API</name>
+  <description>
+    The application programming interface for the repository system.
+  </description>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-library</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/AbstractForwardingRepositorySystemSession.java
----------------------------------------------------------------------
diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/AbstractForwardingRepositorySystemSession.java b/maven-resolver-api/src/main/java/org/eclipse/aether/AbstractForwardingRepositorySystemSession.java
new file mode 100644
index 0000000..20df431
--- /dev/null
+++ b/maven-resolver-api/src/main/java/org/eclipse/aether/AbstractForwardingRepositorySystemSession.java
@@ -0,0 +1,189 @@
+package org.eclipse.aether;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Map;
+
+import org.eclipse.aether.artifact.ArtifactTypeRegistry;
+import org.eclipse.aether.collection.DependencyGraphTransformer;
+import org.eclipse.aether.collection.DependencyManager;
+import org.eclipse.aether.collection.DependencySelector;
+import org.eclipse.aether.collection.DependencyTraverser;
+import org.eclipse.aether.collection.VersionFilter;
+import org.eclipse.aether.repository.AuthenticationSelector;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.LocalRepositoryManager;
+import org.eclipse.aether.repository.MirrorSelector;
+import org.eclipse.aether.repository.ProxySelector;
+import org.eclipse.aether.repository.WorkspaceReader;
+import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
+import org.eclipse.aether.resolution.ResolutionErrorPolicy;
+import org.eclipse.aether.transfer.TransferListener;
+
+/**
+ * A special repository system session to enable decorating or proxying another session. To do so, clients have to
+ * create a subclass and implement {@link #getSession()}.
+ */
+public abstract class AbstractForwardingRepositorySystemSession
+    implements RepositorySystemSession
+{
+
+    /**
+     * Creates a new forwarding session.
+     */
+    protected AbstractForwardingRepositorySystemSession()
+    {
+    }
+
+    /**
+     * Gets the repository system session to which this instance forwards calls. It's worth noting that this class does
+     * not save/cache the returned reference but queries this method before each forwarding. Hence, the session
+     * forwarded to may change over time or depending on the context (e.g. calling thread).
+     * 
+     * @return The repository system session to forward calls to, never {@code null}.
+     */
+    protected abstract RepositorySystemSession getSession();
+
+    public boolean isOffline()
+    {
+        return getSession().isOffline();
+    }
+
+    public boolean isIgnoreArtifactDescriptorRepositories()
+    {
+        return getSession().isIgnoreArtifactDescriptorRepositories();
+    }
+
+    public ResolutionErrorPolicy getResolutionErrorPolicy()
+    {
+        return getSession().getResolutionErrorPolicy();
+    }
+
+    public ArtifactDescriptorPolicy getArtifactDescriptorPolicy()
+    {
+        return getSession().getArtifactDescriptorPolicy();
+    }
+
+    public String getChecksumPolicy()
+    {
+        return getSession().getChecksumPolicy();
+    }
+
+    public String getUpdatePolicy()
+    {
+        return getSession().getUpdatePolicy();
+    }
+
+    public LocalRepository getLocalRepository()
+    {
+        return getSession().getLocalRepository();
+    }
+
+    public LocalRepositoryManager getLocalRepositoryManager()
+    {
+        return getSession().getLocalRepositoryManager();
+    }
+
+    public WorkspaceReader getWorkspaceReader()
+    {
+        return getSession().getWorkspaceReader();
+    }
+
+    public RepositoryListener getRepositoryListener()
+    {
+        return getSession().getRepositoryListener();
+    }
+
+    public TransferListener getTransferListener()
+    {
+        return getSession().getTransferListener();
+    }
+
+    public Map<String, String> getSystemProperties()
+    {
+        return getSession().getSystemProperties();
+    }
+
+    public Map<String, String> getUserProperties()
+    {
+        return getSession().getUserProperties();
+    }
+
+    public Map<String, Object> getConfigProperties()
+    {
+        return getSession().getConfigProperties();
+    }
+
+    public MirrorSelector getMirrorSelector()
+    {
+        return getSession().getMirrorSelector();
+    }
+
+    public ProxySelector getProxySelector()
+    {
+        return getSession().getProxySelector();
+    }
+
+    public AuthenticationSelector getAuthenticationSelector()
+    {
+        return getSession().getAuthenticationSelector();
+    }
+
+    public ArtifactTypeRegistry getArtifactTypeRegistry()
+    {
+        return getSession().getArtifactTypeRegistry();
+    }
+
+    public DependencyTraverser getDependencyTraverser()
+    {
+        return getSession().getDependencyTraverser();
+    }
+
+    public DependencyManager getDependencyManager()
+    {
+        return getSession().getDependencyManager();
+    }
+
+    public DependencySelector getDependencySelector()
+    {
+        return getSession().getDependencySelector();
+    }
+
+    public VersionFilter getVersionFilter()
+    {
+        return getSession().getVersionFilter();
+    }
+
+    public DependencyGraphTransformer getDependencyGraphTransformer()
+    {
+        return getSession().getDependencyGraphTransformer();
+    }
+
+    public SessionData getData()
+    {
+        return getSession().getData();
+    }
+
+    public RepositoryCache getCache()
+    {
+        return getSession().getCache();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/AbstractRepositoryListener.java
----------------------------------------------------------------------
diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/AbstractRepositoryListener.java b/maven-resolver-api/src/main/java/org/eclipse/aether/AbstractRepositoryListener.java
new file mode 100644
index 0000000..f42d15e
--- /dev/null
+++ b/maven-resolver-api/src/main/java/org/eclipse/aether/AbstractRepositoryListener.java
@@ -0,0 +1,112 @@
+package org.eclipse.aether;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A skeleton implementation for custom repository listeners. The callback methods in this class do nothing.
+ */
+public abstract class AbstractRepositoryListener
+    implements RepositoryListener
+{
+
+    /**
+     * Enables subclassing.
+     */
+    protected AbstractRepositoryListener()
+    {
+    }
+
+    public void artifactDeployed( RepositoryEvent event )
+    {
+    }
+
+    public void artifactDeploying( RepositoryEvent event )
+    {
+    }
+
+    public void artifactDescriptorInvalid( RepositoryEvent event )
+    {
+    }
+
+    public void artifactDescriptorMissing( RepositoryEvent event )
+    {
+    }
+
+    public void artifactDownloaded( RepositoryEvent event )
+    {
+    }
+
+    public void artifactDownloading( RepositoryEvent event )
+    {
+    }
+
+    public void artifactInstalled( RepositoryEvent event )
+    {
+    }
+
+    public void artifactInstalling( RepositoryEvent event )
+    {
+    }
+
+    public void artifactResolved( RepositoryEvent event )
+    {
+    }
+
+    public void artifactResolving( RepositoryEvent event )
+    {
+    }
+
+    public void metadataDeployed( RepositoryEvent event )
+    {
+    }
+
+    public void metadataDeploying( RepositoryEvent event )
+    {
+    }
+
+    public void metadataDownloaded( RepositoryEvent event )
+    {
+    }
+
+    public void metadataDownloading( RepositoryEvent event )
+    {
+    }
+
+    public void metadataInstalled( RepositoryEvent event )
+    {
+    }
+
+    public void metadataInstalling( RepositoryEvent event )
+    {
+    }
+
+    public void metadataInvalid( RepositoryEvent event )
+    {
+    }
+
+    public void metadataResolved( RepositoryEvent event )
+    {
+    }
+
+    public void metadataResolving( RepositoryEvent event )
+    {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/ConfigurationProperties.java
----------------------------------------------------------------------
diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/ConfigurationProperties.java b/maven-resolver-api/src/main/java/org/eclipse/aether/ConfigurationProperties.java
new file mode 100644
index 0000000..bc1738f
--- /dev/null
+++ b/maven-resolver-api/src/main/java/org/eclipse/aether/ConfigurationProperties.java
@@ -0,0 +1,152 @@
+package org.eclipse.aether;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * The keys and defaults for common configuration properties.
+ * 
+ * @see RepositorySystemSession#getConfigProperties()
+ */
+public final class ConfigurationProperties
+{
+
+    private static final String PREFIX_AETHER = "aether.";
+
+    private static final String PREFIX_CONNECTOR = PREFIX_AETHER + "connector.";
+
+    /**
+     * The prefix for properties that control the priority of pluggable extensions like transporters. For example, for
+     * an extension with the fully qualified class name "org.eclipse.MyExtensionFactory", the configuration properties
+     * "aether.priority.org.eclipse.MyExtensionFactory", "aether.priority.MyExtensionFactory" and
+     * "aether.priority.MyExtension" will be consulted for the priority, in that order (obviously, the last key is only
+     * tried if the class name ends with "Factory"). The corresponding value is a float and the special value
+     * {@link Float#NaN} or "NaN" (case-sensitive) can be used to disable the extension.
+     */
+    public static final String PREFIX_PRIORITY = PREFIX_AETHER + "priority.";
+
+    /**
+     * A flag indicating whether the priorities of pluggable extensions are implicitly given by their iteration order
+     * such that the first extension has the highest priority. If set, an extension's built-in priority as well as any
+     * corresponding {@code aether.priority.*} configuration properties are ignored when searching for a suitable
+     * implementation among the available extensions. This priority mode is meant for cases where the application will
+     * present/inject extensions in the desired search order.
+     * 
+     * @see #DEFAULT_IMPLICIT_PRIORITIES
+     */
+    public static final String IMPLICIT_PRIORITIES = PREFIX_PRIORITY + "implicit";
+
+    /**
+     * The default extension priority mode if {@link #IMPLICIT_PRIORITIES} isn't set.
+     */
+    public static final boolean DEFAULT_IMPLICIT_PRIORITIES = false;
+
+    /**
+     * A flag indicating whether interaction with the user is allowed.
+     * 
+     * @see #DEFAULT_INTERACTIVE
+     */
+    public static final String INTERACTIVE = PREFIX_AETHER + "interactive";
+
+    /**
+     * The default interactive mode if {@link #INTERACTIVE} isn't set.
+     */
+    public static final boolean DEFAULT_INTERACTIVE = false;
+
+    /**
+     * The user agent that repository connectors should report to servers.
+     * 
+     * @see #DEFAULT_USER_AGENT
+     */
+    public static final String USER_AGENT = PREFIX_CONNECTOR + "userAgent";
+
+    /**
+     * The default user agent to use if {@link #USER_AGENT} isn't set.
+     */
+    public static final String DEFAULT_USER_AGENT = "Aether";
+
+    /**
+     * The maximum amount of time (in milliseconds) to wait for a successful connection to a remote server. Non-positive
+     * values indicate no timeout.
+     * 
+     * @see #DEFAULT_CONNECT_TIMEOUT
+     */
+    public static final String CONNECT_TIMEOUT = PREFIX_CONNECTOR + "connectTimeout";
+
+    /**
+     * The default connect timeout to use if {@link #CONNECT_TIMEOUT} isn't set.
+     */
+    public static final int DEFAULT_CONNECT_TIMEOUT = 10 * 1000;
+
+    /**
+     * The maximum amount of time (in milliseconds) to wait for remaining data to arrive from a remote server. Note that
+     * this timeout does not restrict the overall duration of a request, it only restricts the duration of inactivity
+     * between consecutive data packets. Non-positive values indicate no timeout.
+     * 
+     * @see #DEFAULT_REQUEST_TIMEOUT
+     */
+    public static final String REQUEST_TIMEOUT = PREFIX_CONNECTOR + "requestTimeout";
+
+    /**
+     * The default request timeout to use if {@link #REQUEST_TIMEOUT} isn't set.
+     */
+    public static final int DEFAULT_REQUEST_TIMEOUT = 1800 * 1000;
+
+    /**
+     * The request headers to use for HTTP-based repository connectors. The headers are specified using a
+     * {@code Map<String, String>}, mapping a header name to its value. Besides this general key, clients may also
+     * specify headers for a specific remote repository by appending the suffix {@code .<repoId>} to this key when
+     * storing the headers map. The repository-specific headers map is supposed to be complete, i.e. is not merged with
+     * the general headers map.
+     */
+    public static final String HTTP_HEADERS = PREFIX_CONNECTOR + "http.headers";
+
+    /**
+     * The encoding/charset to use when exchanging credentials with HTTP servers. Besides this general key, clients may
+     * also specify the encoding for a specific remote repository by appending the suffix {@code .<repoId>} to this key
+     * when storing the charset name.
+     * 
+     * @see #DEFAULT_HTTP_CREDENTIAL_ENCODING
+     */
+    public static final String HTTP_CREDENTIAL_ENCODING = PREFIX_CONNECTOR + "http.credentialEncoding";
+
+    /**
+     * The default encoding/charset to use if {@link #HTTP_CREDENTIAL_ENCODING} isn't set.
+     */
+    public static final String DEFAULT_HTTP_CREDENTIAL_ENCODING = "ISO-8859-1";
+
+    /**
+     * A flag indicating whether checksums which are retrieved during checksum validation should be persisted in the
+     * local filesystem next to the file they provide the checksum for.
+     * 
+     * @see #DEFAULT_PERSISTED_CHECKSUMS
+     */
+    public static final String PERSISTED_CHECKSUMS = PREFIX_CONNECTOR + "persistedChecksums";
+
+    /**
+     * The default checksum persistence mode if {@link #PERSISTED_CHECKSUMS} isn't set.
+     */
+    public static final boolean DEFAULT_PERSISTED_CHECKSUMS = true;
+
+    private ConfigurationProperties()
+    {
+        // hide constructor
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/DefaultRepositoryCache.java
----------------------------------------------------------------------
diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/DefaultRepositoryCache.java b/maven-resolver-api/src/main/java/org/eclipse/aether/DefaultRepositoryCache.java
new file mode 100644
index 0000000..b645f43
--- /dev/null
+++ b/maven-resolver-api/src/main/java/org/eclipse/aether/DefaultRepositoryCache.java
@@ -0,0 +1,52 @@
+package org.eclipse.aether;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * A simplistic repository cache backed by a thread-safe map. The simplistic nature of this cache makes it only suitable
+ * for use with short-lived repository system sessions where pruning of cache data is not required.
+ */
+public final class DefaultRepositoryCache
+    implements RepositoryCache
+{
+
+    private final Map<Object, Object> cache = new ConcurrentHashMap<Object, Object>( 256 );
+
+    public Object get( RepositorySystemSession session, Object key )
+    {
+        return cache.get( key );
+    }
+
+    public void put( RepositorySystemSession session, Object key, Object data )
+    {
+        if ( data != null )
+        {
+            cache.put( key, data );
+        }
+        else
+        {
+            cache.remove( key );
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/DefaultRepositorySystemSession.java
----------------------------------------------------------------------
diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/DefaultRepositorySystemSession.java b/maven-resolver-api/src/main/java/org/eclipse/aether/DefaultRepositorySystemSession.java
new file mode 100644
index 0000000..93ebaca
--- /dev/null
+++ b/maven-resolver-api/src/main/java/org/eclipse/aether/DefaultRepositorySystemSession.java
@@ -0,0 +1,834 @@
+package org.eclipse.aether;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.aether.artifact.ArtifactType;
+import org.eclipse.aether.artifact.ArtifactTypeRegistry;
+import org.eclipse.aether.collection.DependencyGraphTransformer;
+import org.eclipse.aether.collection.DependencyManager;
+import org.eclipse.aether.collection.DependencySelector;
+import org.eclipse.aether.collection.DependencyTraverser;
+import org.eclipse.aether.collection.VersionFilter;
+import org.eclipse.aether.repository.Authentication;
+import org.eclipse.aether.repository.AuthenticationSelector;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.LocalRepositoryManager;
+import org.eclipse.aether.repository.MirrorSelector;
+import org.eclipse.aether.repository.Proxy;
+import org.eclipse.aether.repository.ProxySelector;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.repository.RepositoryPolicy;
+import org.eclipse.aether.repository.WorkspaceReader;
+import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
+import org.eclipse.aether.resolution.ResolutionErrorPolicy;
+import org.eclipse.aether.transfer.TransferListener;
+
+/**
+ * A simple repository system session.
+ * <p>
+ * <strong>Note:</strong> This class is not thread-safe. It is assumed that the mutators get only called during an
+ * initialization phase and that the session itself is not changed once initialized and being used by the repository
+ * system. It is recommended to call {@link #setReadOnly()} once the session has been fully initialized to prevent
+ * accidental manipulation of it afterwards.
+ */
+public final class DefaultRepositorySystemSession
+    implements RepositorySystemSession
+{
+
+    private boolean readOnly;
+
+    private boolean offline;
+
+    private boolean ignoreArtifactDescriptorRepositories;
+
+    private ResolutionErrorPolicy resolutionErrorPolicy;
+
+    private ArtifactDescriptorPolicy artifactDescriptorPolicy;
+
+    private String checksumPolicy;
+
+    private String updatePolicy;
+
+    private LocalRepositoryManager localRepositoryManager;
+
+    private WorkspaceReader workspaceReader;
+
+    private RepositoryListener repositoryListener;
+
+    private TransferListener transferListener;
+
+    private Map<String, String> systemProperties;
+
+    private Map<String, String> systemPropertiesView;
+
+    private Map<String, String> userProperties;
+
+    private Map<String, String> userPropertiesView;
+
+    private Map<String, Object> configProperties;
+
+    private Map<String, Object> configPropertiesView;
+
+    private MirrorSelector mirrorSelector;
+
+    private ProxySelector proxySelector;
+
+    private AuthenticationSelector authenticationSelector;
+
+    private ArtifactTypeRegistry artifactTypeRegistry;
+
+    private DependencyTraverser dependencyTraverser;
+
+    private DependencyManager dependencyManager;
+
+    private DependencySelector dependencySelector;
+
+    private VersionFilter versionFilter;
+
+    private DependencyGraphTransformer dependencyGraphTransformer;
+
+    private SessionData data;
+
+    private RepositoryCache cache;
+
+    /**
+     * Creates an uninitialized session. <em>Note:</em> The new session is not ready to use, as a bare minimum,
+     * {@link #setLocalRepositoryManager(LocalRepositoryManager)} needs to be called but usually other settings also
+     * need to be customized to achieve meaningful behavior.
+     */
+    public DefaultRepositorySystemSession()
+    {
+        systemProperties = new HashMap<String, String>();
+        systemPropertiesView = Collections.unmodifiableMap( systemProperties );
+        userProperties = new HashMap<String, String>();
+        userPropertiesView = Collections.unmodifiableMap( userProperties );
+        configProperties = new HashMap<String, Object>();
+        configPropertiesView = Collections.unmodifiableMap( configProperties );
+        mirrorSelector = NullMirrorSelector.INSTANCE;
+        proxySelector = NullProxySelector.INSTANCE;
+        authenticationSelector = NullAuthenticationSelector.INSTANCE;
+        artifactTypeRegistry = NullArtifactTypeRegistry.INSTANCE;
+        data = new DefaultSessionData();
+    }
+
+    /**
+     * Creates a shallow copy of the specified session. Actually, the copy is not completely shallow, all maps holding
+     * system/user/config properties are copied as well. In other words, invoking any mutator on the new session itself
+     * has no effect on the original session. Other mutable objects like the session data and cache (if any) are not
+     * copied and will be shared with the original session unless reconfigured.
+     * 
+     * @param session The session to copy, must not be {@code null}.
+     */
+    public DefaultRepositorySystemSession( RepositorySystemSession session )
+    {
+        if ( session == null )
+        {
+            throw new IllegalArgumentException( "repository system session not specified" );
+        }
+
+        setOffline( session.isOffline() );
+        setIgnoreArtifactDescriptorRepositories( session.isIgnoreArtifactDescriptorRepositories() );
+        setResolutionErrorPolicy( session.getResolutionErrorPolicy() );
+        setArtifactDescriptorPolicy( session.getArtifactDescriptorPolicy() );
+        setChecksumPolicy( session.getChecksumPolicy() );
+        setUpdatePolicy( session.getUpdatePolicy() );
+        setLocalRepositoryManager( session.getLocalRepositoryManager() );
+        setWorkspaceReader( session.getWorkspaceReader() );
+        setRepositoryListener( session.getRepositoryListener() );
+        setTransferListener( session.getTransferListener() );
+        setSystemProperties( session.getSystemProperties() );
+        setUserProperties( session.getUserProperties() );
+        setConfigProperties( session.getConfigProperties() );
+        setMirrorSelector( session.getMirrorSelector() );
+        setProxySelector( session.getProxySelector() );
+        setAuthenticationSelector( session.getAuthenticationSelector() );
+        setArtifactTypeRegistry( session.getArtifactTypeRegistry() );
+        setDependencyTraverser( session.getDependencyTraverser() );
+        setDependencyManager( session.getDependencyManager() );
+        setDependencySelector( session.getDependencySelector() );
+        setVersionFilter( session.getVersionFilter() );
+        setDependencyGraphTransformer( session.getDependencyGraphTransformer() );
+        setData( session.getData() );
+        setCache( session.getCache() );
+    }
+
+    public boolean isOffline()
+    {
+        return offline;
+    }
+
+    /**
+     * Controls whether the repository system operates in offline mode and avoids/refuses any access to remote
+     * repositories.
+     * 
+     * @param offline {@code true} if the repository system is in offline mode, {@code false} otherwise.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setOffline( boolean offline )
+    {
+        failIfReadOnly();
+        this.offline = offline;
+        return this;
+    }
+
+    public boolean isIgnoreArtifactDescriptorRepositories()
+    {
+        return ignoreArtifactDescriptorRepositories;
+    }
+
+    /**
+     * Controls whether repositories declared in artifact descriptors should be ignored during transitive dependency
+     * collection. If enabled, only the repositories originally provided with the collect request will be considered.
+     * 
+     * @param ignoreArtifactDescriptorRepositories {@code true} to ignore additional repositories from artifact
+     *            descriptors, {@code false} to merge those with the originally specified repositories.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setIgnoreArtifactDescriptorRepositories( boolean ignoreArtifactDescriptorRepositories )
+    {
+        failIfReadOnly();
+        this.ignoreArtifactDescriptorRepositories = ignoreArtifactDescriptorRepositories;
+        return this;
+    }
+
+    public ResolutionErrorPolicy getResolutionErrorPolicy()
+    {
+        return resolutionErrorPolicy;
+    }
+
+    /**
+     * Sets the policy which controls whether resolutions errors from remote repositories should be cached.
+     * 
+     * @param resolutionErrorPolicy The resolution error policy for this session, may be {@code null} if resolution
+     *            errors should generally not be cached.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setResolutionErrorPolicy( ResolutionErrorPolicy resolutionErrorPolicy )
+    {
+        failIfReadOnly();
+        this.resolutionErrorPolicy = resolutionErrorPolicy;
+        return this;
+    }
+
+    public ArtifactDescriptorPolicy getArtifactDescriptorPolicy()
+    {
+        return artifactDescriptorPolicy;
+    }
+
+    /**
+     * Sets the policy which controls how errors related to reading artifact descriptors should be handled.
+     * 
+     * @param artifactDescriptorPolicy The descriptor error policy for this session, may be {@code null} if descriptor
+     *            errors should generally not be tolerated.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setArtifactDescriptorPolicy( ArtifactDescriptorPolicy artifactDescriptorPolicy )
+    {
+        failIfReadOnly();
+        this.artifactDescriptorPolicy = artifactDescriptorPolicy;
+        return this;
+    }
+
+    public String getChecksumPolicy()
+    {
+        return checksumPolicy;
+    }
+
+    /**
+     * Sets the global checksum policy. If set, the global checksum policy overrides the checksum policies of the remote
+     * repositories being used for resolution.
+     * 
+     * @param checksumPolicy The global checksum policy, may be {@code null}/empty to apply the per-repository policies.
+     * @return This session for chaining, never {@code null}.
+     * @see RepositoryPolicy#CHECKSUM_POLICY_FAIL
+     * @see RepositoryPolicy#CHECKSUM_POLICY_IGNORE
+     * @see RepositoryPolicy#CHECKSUM_POLICY_WARN
+     */
+    public DefaultRepositorySystemSession setChecksumPolicy( String checksumPolicy )
+    {
+        failIfReadOnly();
+        this.checksumPolicy = checksumPolicy;
+        return this;
+    }
+
+    public String getUpdatePolicy()
+    {
+        return updatePolicy;
+    }
+
+    /**
+     * Sets the global update policy. If set, the global update policy overrides the update policies of the remote
+     * repositories being used for resolution.
+     * 
+     * @param updatePolicy The global update policy, may be {@code null}/empty to apply the per-repository policies.
+     * @return This session for chaining, never {@code null}.
+     * @see RepositoryPolicy#UPDATE_POLICY_ALWAYS
+     * @see RepositoryPolicy#UPDATE_POLICY_DAILY
+     * @see RepositoryPolicy#UPDATE_POLICY_NEVER
+     */
+    public DefaultRepositorySystemSession setUpdatePolicy( String updatePolicy )
+    {
+        failIfReadOnly();
+        this.updatePolicy = updatePolicy;
+        return this;
+    }
+
+    public LocalRepository getLocalRepository()
+    {
+        LocalRepositoryManager lrm = getLocalRepositoryManager();
+        return ( lrm != null ) ? lrm.getRepository() : null;
+    }
+
+    public LocalRepositoryManager getLocalRepositoryManager()
+    {
+        return localRepositoryManager;
+    }
+
+    /**
+     * Sets the local repository manager used during this session. <em>Note:</em> Eventually, a valid session must have
+     * a local repository manager set.
+     * 
+     * @param localRepositoryManager The local repository manager used during this session, may be {@code null}.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setLocalRepositoryManager( LocalRepositoryManager localRepositoryManager )
+    {
+        failIfReadOnly();
+        this.localRepositoryManager = localRepositoryManager;
+        return this;
+    }
+
+    public WorkspaceReader getWorkspaceReader()
+    {
+        return workspaceReader;
+    }
+
+    /**
+     * Sets the workspace reader used during this session. If set, the workspace reader will usually be consulted first
+     * to resolve artifacts.
+     * 
+     * @param workspaceReader The workspace reader for this session, may be {@code null} if none.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setWorkspaceReader( WorkspaceReader workspaceReader )
+    {
+        failIfReadOnly();
+        this.workspaceReader = workspaceReader;
+        return this;
+    }
+
+    public RepositoryListener getRepositoryListener()
+    {
+        return repositoryListener;
+    }
+
+    /**
+     * Sets the listener being notified of actions in the repository system.
+     * 
+     * @param repositoryListener The repository listener, may be {@code null} if none.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setRepositoryListener( RepositoryListener repositoryListener )
+    {
+        failIfReadOnly();
+        this.repositoryListener = repositoryListener;
+        return this;
+    }
+
+    public TransferListener getTransferListener()
+    {
+        return transferListener;
+    }
+
+    /**
+     * Sets the listener being notified of uploads/downloads by the repository system.
+     * 
+     * @param transferListener The transfer listener, may be {@code null} if none.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setTransferListener( TransferListener transferListener )
+    {
+        failIfReadOnly();
+        this.transferListener = transferListener;
+        return this;
+    }
+
+    private <T> Map<String, T> copySafe( Map<?, ?> table, Class<T> valueType )
+    {
+        Map<String, T> map;
+        if ( table == null || table.isEmpty() )
+        {
+            map = new HashMap<String, T>();
+        }
+        else
+        {
+            map = new HashMap<String, T>( (int) ( table.size() / 0.75f ) + 1 );
+            for ( Map.Entry<?, ?> entry : table.entrySet() )
+            {
+                Object key = entry.getKey();
+                if ( key instanceof String )
+                {
+                    Object value = entry.getValue();
+                    if ( valueType.isInstance( value ) )
+                    {
+                        map.put( key.toString(), valueType.cast( value ) );
+                    }
+                }
+            }
+        }
+        return map;
+    }
+
+    public Map<String, String> getSystemProperties()
+    {
+        return systemPropertiesView;
+    }
+
+    /**
+     * Sets the system properties to use, e.g. for processing of artifact descriptors. System properties are usually
+     * collected from the runtime environment like {@link System#getProperties()} and environment variables.
+     * <p>
+     * <em>Note:</em> System properties are of type {@code Map<String, String>} and any key-value pair in the input map
+     * that doesn't match this type will be silently ignored.
+     * 
+     * @param systemProperties The system properties, may be {@code null} or empty if none.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setSystemProperties( Map<?, ?> systemProperties )
+    {
+        failIfReadOnly();
+        this.systemProperties = copySafe( systemProperties, String.class );
+        systemPropertiesView = Collections.unmodifiableMap( this.systemProperties );
+        return this;
+    }
+
+    /**
+     * Sets the specified system property.
+     * 
+     * @param key The property key, must not be {@code null}.
+     * @param value The property value, may be {@code null} to remove/unset the property.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setSystemProperty( String key, String value )
+    {
+        failIfReadOnly();
+        if ( value != null )
+        {
+            systemProperties.put( key, value );
+        }
+        else
+        {
+            systemProperties.remove( key );
+        }
+        return this;
+    }
+
+    public Map<String, String> getUserProperties()
+    {
+        return userPropertiesView;
+    }
+
+    /**
+     * Sets the user properties to use, e.g. for processing of artifact descriptors. User properties are similar to
+     * system properties but are set on the discretion of the user and hence are considered of higher priority than
+     * system properties in case of conflicts.
+     * <p>
+     * <em>Note:</em> User properties are of type {@code Map<String, String>} and any key-value pair in the input map
+     * that doesn't match this type will be silently ignored.
+     * 
+     * @param userProperties The user properties, may be {@code null} or empty if none.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setUserProperties( Map<?, ?> userProperties )
+    {
+        failIfReadOnly();
+        this.userProperties = copySafe( userProperties, String.class );
+        userPropertiesView = Collections.unmodifiableMap( this.userProperties );
+        return this;
+    }
+
+    /**
+     * Sets the specified user property.
+     * 
+     * @param key The property key, must not be {@code null}.
+     * @param value The property value, may be {@code null} to remove/unset the property.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setUserProperty( String key, String value )
+    {
+        failIfReadOnly();
+        if ( value != null )
+        {
+            userProperties.put( key, value );
+        }
+        else
+        {
+            userProperties.remove( key );
+        }
+        return this;
+    }
+
+    public Map<String, Object> getConfigProperties()
+    {
+        return configPropertiesView;
+    }
+
+    /**
+     * Sets the configuration properties used to tweak internal aspects of the repository system (e.g. thread pooling,
+     * connector-specific behavior, etc.).
+     * <p>
+     * <em>Note:</em> Configuration properties are of type {@code Map<String, Object>} and any key-value pair in the
+     * input map that doesn't match this type will be silently ignored.
+     * 
+     * @param configProperties The configuration properties, may be {@code null} or empty if none.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setConfigProperties( Map<?, ?> configProperties )
+    {
+        failIfReadOnly();
+        this.configProperties = copySafe( configProperties, Object.class );
+        configPropertiesView = Collections.unmodifiableMap( this.configProperties );
+        return this;
+    }
+
+    /**
+     * Sets the specified configuration property.
+     * 
+     * @param key The property key, must not be {@code null}.
+     * @param value The property value, may be {@code null} to remove/unset the property.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setConfigProperty( String key, Object value )
+    {
+        failIfReadOnly();
+        if ( value != null )
+        {
+            configProperties.put( key, value );
+        }
+        else
+        {
+            configProperties.remove( key );
+        }
+        return this;
+    }
+
+    public MirrorSelector getMirrorSelector()
+    {
+        return mirrorSelector;
+    }
+
+    /**
+     * Sets the mirror selector to use for repositories discovered in artifact descriptors. Note that this selector is
+     * not used for remote repositories which are passed as request parameters to the repository system, those
+     * repositories are supposed to denote the effective repositories.
+     * 
+     * @param mirrorSelector The mirror selector to use, may be {@code null}.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setMirrorSelector( MirrorSelector mirrorSelector )
+    {
+        failIfReadOnly();
+        this.mirrorSelector = mirrorSelector;
+        if ( this.mirrorSelector == null )
+        {
+            this.mirrorSelector = NullMirrorSelector.INSTANCE;
+        }
+        return this;
+    }
+
+    public ProxySelector getProxySelector()
+    {
+        return proxySelector;
+    }
+
+    /**
+     * Sets the proxy selector to use for repositories discovered in artifact descriptors. Note that this selector is
+     * not used for remote repositories which are passed as request parameters to the repository system, those
+     * repositories are supposed to have their proxy (if any) already set.
+     * 
+     * @param proxySelector The proxy selector to use, may be {@code null}.
+     * @return This session for chaining, never {@code null}.
+     * @see org.eclipse.aether.repository.RemoteRepository#getProxy()
+     */
+    public DefaultRepositorySystemSession setProxySelector( ProxySelector proxySelector )
+    {
+        failIfReadOnly();
+        this.proxySelector = proxySelector;
+        if ( this.proxySelector == null )
+        {
+            this.proxySelector = NullProxySelector.INSTANCE;
+        }
+        return this;
+    }
+
+    public AuthenticationSelector getAuthenticationSelector()
+    {
+        return authenticationSelector;
+    }
+
+    /**
+     * Sets the authentication selector to use for repositories discovered in artifact descriptors. Note that this
+     * selector is not used for remote repositories which are passed as request parameters to the repository system,
+     * those repositories are supposed to have their authentication (if any) already set.
+     * 
+     * @param authenticationSelector The authentication selector to use, may be {@code null}.
+     * @return This session for chaining, never {@code null}.
+     * @see org.eclipse.aether.repository.RemoteRepository#getAuthentication()
+     */
+    public DefaultRepositorySystemSession setAuthenticationSelector( AuthenticationSelector authenticationSelector )
+    {
+        failIfReadOnly();
+        this.authenticationSelector = authenticationSelector;
+        if ( this.authenticationSelector == null )
+        {
+            this.authenticationSelector = NullAuthenticationSelector.INSTANCE;
+        }
+        return this;
+    }
+
+    public ArtifactTypeRegistry getArtifactTypeRegistry()
+    {
+        return artifactTypeRegistry;
+    }
+
+    /**
+     * Sets the registry of artifact types recognized by this session.
+     * 
+     * @param artifactTypeRegistry The artifact type registry, may be {@code null}.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setArtifactTypeRegistry( ArtifactTypeRegistry artifactTypeRegistry )
+    {
+        failIfReadOnly();
+        this.artifactTypeRegistry = artifactTypeRegistry;
+        if ( this.artifactTypeRegistry == null )
+        {
+            this.artifactTypeRegistry = NullArtifactTypeRegistry.INSTANCE;
+        }
+        return this;
+    }
+
+    public DependencyTraverser getDependencyTraverser()
+    {
+        return dependencyTraverser;
+    }
+
+    /**
+     * Sets the dependency traverser to use for building dependency graphs.
+     * 
+     * @param dependencyTraverser The dependency traverser to use for building dependency graphs, may be {@code null}.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setDependencyTraverser( DependencyTraverser dependencyTraverser )
+    {
+        failIfReadOnly();
+        this.dependencyTraverser = dependencyTraverser;
+        return this;
+    }
+
+    public DependencyManager getDependencyManager()
+    {
+        return dependencyManager;
+    }
+
+    /**
+     * Sets the dependency manager to use for building dependency graphs.
+     * 
+     * @param dependencyManager The dependency manager to use for building dependency graphs, may be {@code null}.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setDependencyManager( DependencyManager dependencyManager )
+    {
+        failIfReadOnly();
+        this.dependencyManager = dependencyManager;
+        return this;
+    }
+
+    public DependencySelector getDependencySelector()
+    {
+        return dependencySelector;
+    }
+
+    /**
+     * Sets the dependency selector to use for building dependency graphs.
+     * 
+     * @param dependencySelector The dependency selector to use for building dependency graphs, may be {@code null}.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setDependencySelector( DependencySelector dependencySelector )
+    {
+        failIfReadOnly();
+        this.dependencySelector = dependencySelector;
+        return this;
+    }
+
+    public VersionFilter getVersionFilter()
+    {
+        return versionFilter;
+    }
+
+    /**
+     * Sets the version filter to use for building dependency graphs.
+     * 
+     * @param versionFilter The version filter to use for building dependency graphs, may be {@code null} to not filter
+     *            versions.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setVersionFilter( VersionFilter versionFilter )
+    {
+        failIfReadOnly();
+        this.versionFilter = versionFilter;
+        return this;
+    }
+
+    public DependencyGraphTransformer getDependencyGraphTransformer()
+    {
+        return dependencyGraphTransformer;
+    }
+
+    /**
+     * Sets the dependency graph transformer to use for building dependency graphs.
+     * 
+     * @param dependencyGraphTransformer The dependency graph transformer to use for building dependency graphs, may be
+     *            {@code null}.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setDependencyGraphTransformer( DependencyGraphTransformer dependencyGraphTransformer )
+    {
+        failIfReadOnly();
+        this.dependencyGraphTransformer = dependencyGraphTransformer;
+        return this;
+    }
+
+    public SessionData getData()
+    {
+        return data;
+    }
+
+    /**
+     * Sets the custom data associated with this session.
+     * 
+     * @param data The session data, may be {@code null}.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setData( SessionData data )
+    {
+        failIfReadOnly();
+        this.data = data;
+        if ( this.data == null )
+        {
+            this.data = new DefaultSessionData();
+        }
+        return this;
+    }
+
+    public RepositoryCache getCache()
+    {
+        return cache;
+    }
+
+    /**
+     * Sets the cache the repository system may use to save data for future reuse during the session.
+     * 
+     * @param cache The repository cache, may be {@code null} if none.
+     * @return This session for chaining, never {@code null}.
+     */
+    public DefaultRepositorySystemSession setCache( RepositoryCache cache )
+    {
+        failIfReadOnly();
+        this.cache = cache;
+        return this;
+    }
+
+    /**
+     * Marks this session as read-only such that any future attempts to call its mutators will fail with an exception.
+     * Marking an already read-only session as read-only has no effect. The session's data and cache remain writable
+     * though.
+     */
+    public void setReadOnly()
+    {
+        readOnly = true;
+    }
+
+    private void failIfReadOnly()
+    {
+        if ( readOnly )
+        {
+            throw new IllegalStateException( "repository system session is read-only" );
+        }
+    }
+
+    static class NullProxySelector
+        implements ProxySelector
+    {
+
+        public static final ProxySelector INSTANCE = new NullProxySelector();
+
+        public Proxy getProxy( RemoteRepository repository )
+        {
+            return repository.getProxy();
+        }
+
+    }
+
+    static class NullMirrorSelector
+        implements MirrorSelector
+    {
+
+        public static final MirrorSelector INSTANCE = new NullMirrorSelector();
+
+        public RemoteRepository getMirror( RemoteRepository repository )
+        {
+            return null;
+        }
+
+    }
+
+    static class NullAuthenticationSelector
+        implements AuthenticationSelector
+    {
+
+        public static final AuthenticationSelector INSTANCE = new NullAuthenticationSelector();
+
+        public Authentication getAuthentication( RemoteRepository repository )
+        {
+            return repository.getAuthentication();
+        }
+
+    }
+
+    static final class NullArtifactTypeRegistry
+        implements ArtifactTypeRegistry
+    {
+
+        public static final ArtifactTypeRegistry INSTANCE = new NullArtifactTypeRegistry();
+
+        public ArtifactType get( String typeId )
+        {
+            return null;
+        }
+
+    }
+
+}