http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactRequest.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactRequest.java
 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactRequest.java
new file mode 100644
index 0000000..a220207
--- /dev/null
+++ 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactRequest.java
@@ -0,0 +1,232 @@
+package org.eclipse.aether.resolution;
+
+/*
+ * 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.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.graph.DependencyNode;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * A request to resolve an artifact.
+ * 
+ * @see RepositorySystem#resolveArtifacts(RepositorySystemSession, 
java.util.Collection)
+ * @see Artifact#getFile()
+ */
+public final class ArtifactRequest
+{
+
+    private Artifact artifact;
+
+    private DependencyNode node;
+
+    private List<RemoteRepository> repositories = Collections.emptyList();
+
+    private String context = "";
+
+    private RequestTrace trace;
+
+    /**
+     * Creates an uninitialized request.
+     */
+    public ArtifactRequest()
+    {
+        // enables default constructor
+    }
+
+    /**
+     * Creates a request with the specified properties.
+     * 
+     * @param artifact The artifact to resolve, may be {@code null}.
+     * @param repositories The repositories to resolve the artifact from, may 
be {@code null}.
+     * @param context The context in which this request is made, may be {@code 
null}.
+     */
+    public ArtifactRequest( Artifact artifact, List<RemoteRepository> 
repositories, String context )
+    {
+        setArtifact( artifact );
+        setRepositories( repositories );
+        setRequestContext( context );
+    }
+
+    /**
+     * Creates a request from the specified dependency node.
+     * 
+     * @param node The dependency node to resolve, may be {@code null}.
+     */
+    public ArtifactRequest( DependencyNode node )
+    {
+        setDependencyNode( node );
+        setRepositories( node.getRepositories() );
+        setRequestContext( node.getRequestContext() );
+    }
+
+    /**
+     * Gets the artifact to resolve.
+     * 
+     * @return The artifact to resolve or {@code null}.
+     */
+    public Artifact getArtifact()
+    {
+        return artifact;
+    }
+
+    /**
+     * Sets the artifact to resolve.
+     * 
+     * @param artifact The artifact to resolve, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public ArtifactRequest setArtifact( Artifact artifact )
+    {
+        this.artifact = artifact;
+        return this;
+    }
+
+    /**
+     * Gets the dependency node (if any) for which to resolve the artifact.
+     * 
+     * @return The dependency node to resolve or {@code null} if unknown.
+     */
+    public DependencyNode getDependencyNode()
+    {
+        return node;
+    }
+
+    /**
+     * Sets the dependency node to resolve.
+     * 
+     * @param node The dependency node to resolve, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public ArtifactRequest setDependencyNode( DependencyNode node )
+    {
+        this.node = node;
+        if ( node != null )
+        {
+            setArtifact( node.getDependency().getArtifact() );
+        }
+        return this;
+    }
+
+    /**
+     * Gets the repositories to resolve the artifact from.
+     * 
+     * @return The repositories, never {@code null}.
+     */
+    public List<RemoteRepository> getRepositories()
+    {
+        return repositories;
+    }
+
+    /**
+     * Sets the repositories to resolve the artifact from.
+     * 
+     * @param repositories The repositories, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public ArtifactRequest setRepositories( List<RemoteRepository> 
repositories )
+    {
+        if ( repositories == null )
+        {
+            this.repositories = Collections.emptyList();
+        }
+        else
+        {
+            this.repositories = repositories;
+        }
+        return this;
+    }
+
+    /**
+     * Adds the specified repository for the resolution.
+     * 
+     * @param repository The repository to add, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public ArtifactRequest addRepository( RemoteRepository repository )
+    {
+        if ( repository != null )
+        {
+            if ( this.repositories.isEmpty() )
+            {
+                this.repositories = new ArrayList<RemoteRepository>();
+            }
+            this.repositories.add( repository );
+        }
+        return this;
+    }
+
+    /**
+     * Gets the context in which this request is made.
+     * 
+     * @return The context, never {@code null}.
+     */
+    public String getRequestContext()
+    {
+        return context;
+    }
+
+    /**
+     * Sets the context in which this request is made.
+     * 
+     * @param context The context, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public ArtifactRequest setRequestContext( String context )
+    {
+        this.context = ( context != null ) ? context : "";
+        return this;
+    }
+
+    /**
+     * Gets the trace information that describes the higher level 
request/operation in which this request is issued.
+     * 
+     * @return The trace information about the higher level operation or 
{@code null} if none.
+     */
+    public RequestTrace getTrace()
+    {
+        return trace;
+    }
+
+    /**
+     * Sets the trace information that describes the higher level 
request/operation in which this request is issued.
+     * 
+     * @param trace The trace information about the higher level operation, 
may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public ArtifactRequest setTrace( RequestTrace trace )
+    {
+        this.trace = trace;
+        return this;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getArtifact() + " < " + getRepositories();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResolutionException.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResolutionException.java
 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResolutionException.java
new file mode 100644
index 0000000..bfae4a0
--- /dev/null
+++ 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResolutionException.java
@@ -0,0 +1,173 @@
+package org.eclipse.aether.resolution;
+
+/*
+ * 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.List;
+
+import org.eclipse.aether.RepositoryException;
+import org.eclipse.aether.transfer.ArtifactNotFoundException;
+import org.eclipse.aether.transfer.RepositoryOfflineException;
+
+/**
+ * Thrown in case of a unresolvable artifacts.
+ */
+public class ArtifactResolutionException
+    extends RepositoryException
+{
+
+    private final transient List<ArtifactResult> results;
+
+    /**
+     * Creates a new exception with the specified results.
+     * 
+     * @param results The resolution results at the point the exception 
occurred, may be {@code null}.
+     */
+    public ArtifactResolutionException( List<ArtifactResult> results )
+    {
+        super( getMessage( results ), getCause( results ) );
+        this.results = ( results != null ) ? results : 
Collections.<ArtifactResult>emptyList();
+    }
+
+    /**
+     * Creates a new exception with the specified results and detail message.
+     * 
+     * @param results The resolution results at the point the exception 
occurred, may be {@code null}.
+     * @param message The detail message, may be {@code null}.
+     */
+    public ArtifactResolutionException( List<ArtifactResult> results, String 
message )
+    {
+        super( message, getCause( results ) );
+        this.results = ( results != null ) ? results : 
Collections.<ArtifactResult>emptyList();
+    }
+
+    /**
+     * Creates a new exception with the specified results, detail message and 
cause.
+     * 
+     * @param results The resolution results at the point the exception 
occurred, may be {@code null}.
+     * @param message The detail message, may be {@code null}.
+     * @param cause The exception that caused this one, may be {@code null}.
+     */
+    public ArtifactResolutionException( List<ArtifactResult> results, String 
message, Throwable cause )
+    {
+        super( message, cause );
+        this.results = ( results != null ) ? results : 
Collections.<ArtifactResult>emptyList();
+    }
+
+    /**
+     * Gets the resolution results at the point the exception occurred. 
Despite being incomplete, callers might want to
+     * use these results to fail gracefully and continue their operation with 
whatever interim data has been gathered.
+     * 
+     * @return The resolution results or {@code null} if unknown.
+     */
+    public List<ArtifactResult> getResults()
+    {
+        return results;
+    }
+
+    /**
+     * Gets the first result from {@link #getResults()}. This is a convenience 
method for cases where callers know only
+     * a single result/request is involved.
+     * 
+     * @return The (first) resolution result or {@code null} if none.
+     */
+    public ArtifactResult getResult()
+    {
+        return ( results != null && !results.isEmpty() ) ? results.get( 0 ) : 
null;
+    }
+
+    private static String getMessage( List<? extends ArtifactResult> results )
+    {
+        StringBuilder buffer = new StringBuilder( 256 );
+
+        buffer.append( "The following artifacts could not be resolved: " );
+
+        int unresolved = 0;
+
+        String sep = "";
+        for ( ArtifactResult result : results )
+        {
+            if ( !result.isResolved() )
+            {
+                unresolved++;
+
+                buffer.append( sep );
+                buffer.append( result.getRequest().getArtifact() );
+                sep = ", ";
+            }
+        }
+
+        Throwable cause = getCause( results );
+        if ( cause != null )
+        {
+            if ( unresolved == 1 )
+            {
+                buffer.setLength( 0 );
+                buffer.append( cause.getMessage() );
+            }
+            else
+            {
+                buffer.append( ": " ).append( cause.getMessage() );
+            }
+        }
+
+        return buffer.toString();
+    }
+
+    private static Throwable getCause( List<? extends ArtifactResult> results )
+    {
+        for ( ArtifactResult result : results )
+        {
+            if ( !result.isResolved() )
+            {
+                Throwable notFound = null, offline = null;
+                for ( Throwable t : result.getExceptions() )
+                {
+                    if ( t instanceof ArtifactNotFoundException )
+                    {
+                        if ( notFound == null )
+                        {
+                            notFound = t;
+                        }
+                        if ( offline == null && t.getCause() instanceof 
RepositoryOfflineException )
+                        {
+                            offline = t;
+                        }
+                    }
+                    else
+                    {
+                        return t;
+                    }
+
+                }
+                if ( offline != null )
+                {
+                    return offline;
+                }
+                if ( notFound != null )
+                {
+                    return notFound;
+                }
+            }
+        }
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResult.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResult.java
 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResult.java
new file mode 100644
index 0000000..5ae820b
--- /dev/null
+++ 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResult.java
@@ -0,0 +1,188 @@
+package org.eclipse.aether.resolution;
+
+/*
+ * 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.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.repository.ArtifactRepository;
+import org.eclipse.aether.transfer.ArtifactNotFoundException;
+
+/**
+ * The result of an artifact resolution request.
+ * 
+ * @see RepositorySystem#resolveArtifacts(RepositorySystemSession, 
java.util.Collection)
+ * @see Artifact#getFile()
+ */
+public final class ArtifactResult
+{
+
+    private final ArtifactRequest request;
+
+    private List<Exception> exceptions;
+
+    private Artifact artifact;
+
+    private ArtifactRepository repository;
+
+    /**
+     * Creates a new result for the specified request.
+     * 
+     * @param request The resolution request, must not be {@code null}.
+     */
+    public ArtifactResult( ArtifactRequest request )
+    {
+        if ( request == null )
+        {
+            throw new IllegalArgumentException( "resolution request has not 
been specified" );
+        }
+        this.request = request;
+        exceptions = Collections.emptyList();
+    }
+
+    /**
+     * Gets the resolution request that was made.
+     * 
+     * @return The resolution request, never {@code null}.
+     */
+    public ArtifactRequest getRequest()
+    {
+        return request;
+    }
+
+    /**
+     * Gets the resolved artifact (if any). Use {@link #getExceptions()} to 
query the errors that occurred while trying
+     * to resolve the artifact.
+     * 
+     * @return The resolved artifact or {@code null} if the resolution failed.
+     */
+    public Artifact getArtifact()
+    {
+        return artifact;
+    }
+
+    /**
+     * Sets the resolved artifact.
+     * 
+     * @param artifact The resolved artifact, may be {@code null} if the 
resolution failed.
+     * @return This result for chaining, never {@code null}.
+     */
+    public ArtifactResult setArtifact( Artifact artifact )
+    {
+        this.artifact = artifact;
+        return this;
+    }
+
+    /**
+     * Gets the exceptions that occurred while resolving the artifact. Note 
that this list can be non-empty even if the
+     * artifact was successfully resolved, e.g. when one of the contacted 
remote repositories didn't contain the
+     * artifact but a later repository eventually contained it.
+     * 
+     * @return The exceptions that occurred, never {@code null}.
+     * @see #isResolved()
+     */
+    public List<Exception> getExceptions()
+    {
+        return exceptions;
+    }
+
+    /**
+     * Records the specified exception while resolving the artifact.
+     * 
+     * @param exception The exception to record, may be {@code null}.
+     * @return This result for chaining, never {@code null}.
+     */
+    public ArtifactResult addException( Exception exception )
+    {
+        if ( exception != null )
+        {
+            if ( exceptions.isEmpty() )
+            {
+                exceptions = new ArrayList<Exception>();
+            }
+            exceptions.add( exception );
+        }
+        return this;
+    }
+
+    /**
+     * Gets the repository from which the artifact was eventually resolved. 
Note that successive resolutions of the same
+     * artifact might yield different results if the employed local repository 
does not track the origin of an artifact.
+     * 
+     * @return The repository from which the artifact was resolved or {@code 
null} if unknown.
+     */
+    public ArtifactRepository getRepository()
+    {
+        return repository;
+    }
+
+    /**
+     * Sets the repository from which the artifact was resolved.
+     * 
+     * @param repository The repository from which the artifact was resolved, 
may be {@code null}.
+     * @return This result for chaining, never {@code null}.
+     */
+    public ArtifactResult setRepository( ArtifactRepository repository )
+    {
+        this.repository = repository;
+        return this;
+    }
+
+    /**
+     * Indicates whether the requested artifact was resolved. Note that the 
artifact might have been successfully
+     * resolved despite {@link #getExceptions()} indicating transfer errors 
while trying to fetch the artifact from some
+     * of the specified remote repositories.
+     * 
+     * @return {@code true} if the artifact was resolved, {@code false} 
otherwise.
+     * @see Artifact#getFile()
+     */
+    public boolean isResolved()
+    {
+        return getArtifact() != null && getArtifact().getFile() != null;
+    }
+
+    /**
+     * Indicates whether the requested artifact is not present in any of the 
specified repositories.
+     * 
+     * @return {@code true} if the artifact is not present in any repository, 
{@code false} otherwise.
+     */
+    public boolean isMissing()
+    {
+        for ( Exception e : getExceptions() )
+        {
+            if ( !( e instanceof ArtifactNotFoundException ) )
+            {
+                return false;
+            }
+        }
+        return !isResolved();
+    }
+
+    @Override
+    public String toString()
+    {
+        return getArtifact() + " < " + getRepository();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyRequest.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyRequest.java
 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyRequest.java
new file mode 100644
index 0000000..138304a
--- /dev/null
+++ 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyRequest.java
@@ -0,0 +1,187 @@
+package org.eclipse.aether.resolution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.collection.CollectRequest;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.graph.DependencyNode;
+
+/**
+ * A request to resolve transitive dependencies. This request can either be 
supplied with a {@link CollectRequest} to
+ * calculate the transitive dependencies or with an already resolved 
dependency graph.
+ * 
+ * @see RepositorySystem#resolveDependencies(RepositorySystemSession, 
DependencyRequest)
+ * @see Artifact#getFile()
+ */
+public final class DependencyRequest
+{
+
+    private DependencyNode root;
+
+    private CollectRequest collectRequest;
+
+    private DependencyFilter filter;
+
+    private RequestTrace trace;
+
+    /**
+     * Creates an uninitialized request. Note that either {@link 
#setRoot(DependencyNode)} or
+     * {@link #setCollectRequest(CollectRequest)} must eventually be called to 
create a valid request.
+     */
+    public DependencyRequest()
+    {
+        // enables default constructor
+    }
+
+    /**
+     * Creates a request for the specified dependency graph and with the given 
resolution filter.
+     * 
+     * @param node The root node of the dependency graph whose artifacts 
should be resolved, may be {@code null}.
+     * @param filter The resolution filter to use, may be {@code null}.
+     */
+    public DependencyRequest( DependencyNode node, DependencyFilter filter )
+    {
+        setRoot( node );
+        setFilter( filter );
+    }
+
+    /**
+     * Creates a request for the specified collect request and with the given 
resolution filter.
+     * 
+     * @param request The collect request used to calculate the dependency 
graph whose artifacts should be resolved, may
+     *            be {@code null}.
+     * @param filter The resolution filter to use, may be {@code null}.
+     */
+    public DependencyRequest( CollectRequest request, DependencyFilter filter )
+    {
+        setCollectRequest( request );
+        setFilter( filter );
+    }
+
+    /**
+     * Gets the root node of the dependency graph whose artifacts should be 
resolved.
+     * 
+     * @return The root node of the dependency graph or {@code null} if none.
+     */
+    public DependencyNode getRoot()
+    {
+        return root;
+    }
+
+    /**
+     * Sets the root node of the dependency graph whose artifacts should be 
resolved. When this request is processed,
+     * the nodes of the given dependency graph will be updated to refer to the 
resolved artifacts. Eventually, either
+     * {@link #setRoot(DependencyNode)} or {@link 
#setCollectRequest(CollectRequest)} must be called to create a valid
+     * request.
+     * 
+     * @param root The root node of the dependency graph, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public DependencyRequest setRoot( DependencyNode root )
+    {
+        this.root = root;
+        return this;
+    }
+
+    /**
+     * Gets the collect request used to calculate the dependency graph whose 
artifacts should be resolved.
+     * 
+     * @return The collect request or {@code null} if none.
+     */
+    public CollectRequest getCollectRequest()
+    {
+        return collectRequest;
+    }
+
+    /**
+     * Sets the collect request used to calculate the dependency graph whose 
artifacts should be resolved. Eventually,
+     * either {@link #setRoot(DependencyNode)} or {@link 
#setCollectRequest(CollectRequest)} must be called to create a
+     * valid request. If this request is supplied with a dependency node via 
{@link #setRoot(DependencyNode)}, the
+     * collect request is ignored.
+     * 
+     * @param collectRequest The collect request, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public DependencyRequest setCollectRequest( CollectRequest collectRequest )
+    {
+        this.collectRequest = collectRequest;
+        return this;
+    }
+
+    /**
+     * Gets the resolution filter used to select which artifacts of the 
dependency graph should be resolved.
+     * 
+     * @return The resolution filter or {@code null} to resolve all artifacts 
of the dependency graph.
+     */
+    public DependencyFilter getFilter()
+    {
+        return filter;
+    }
+
+    /**
+     * Sets the resolution filter used to select which artifacts of the 
dependency graph should be resolved. For
+     * example, use this filter to restrict resolution to dependencies of a 
certain scope.
+     * 
+     * @param filter The resolution filter, may be {@code null} to resolve all 
artifacts of the dependency graph.
+     * @return This request for chaining, never {@code null}.
+     */
+    public DependencyRequest setFilter( DependencyFilter filter )
+    {
+        this.filter = filter;
+        return this;
+    }
+
+    /**
+     * Gets the trace information that describes the higher level 
request/operation in which this request is issued.
+     * 
+     * @return The trace information about the higher level operation or 
{@code null} if none.
+     */
+    public RequestTrace getTrace()
+    {
+        return trace;
+    }
+
+    /**
+     * Sets the trace information that describes the higher level 
request/operation in which this request is issued.
+     * 
+     * @param trace The trace information about the higher level operation, 
may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public DependencyRequest setTrace( RequestTrace trace )
+    {
+        this.trace = trace;
+        return this;
+    }
+
+    @Override
+    public String toString()
+    {
+        if ( root != null )
+        {
+            return String.valueOf( root );
+        }
+        return String.valueOf( collectRequest );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResolutionException.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResolutionException.java
 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResolutionException.java
new file mode 100644
index 0000000..2c12b57
--- /dev/null
+++ 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResolutionException.java
@@ -0,0 +1,83 @@
+package org.eclipse.aether.resolution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.RepositoryException;
+
+/**
+ * Thrown in case of a unresolvable dependencies.
+ */
+public class DependencyResolutionException
+    extends RepositoryException
+{
+
+    private final transient DependencyResult result;
+
+    /**
+     * Creates a new exception with the specified result and cause.
+     * 
+     * @param result The dependency result at the point the exception 
occurred, may be {@code null}.
+     * @param cause The exception that caused this one, may be {@code null}.
+     */
+    public DependencyResolutionException( DependencyResult result, Throwable 
cause )
+    {
+        super( getMessage( cause ), cause );
+        this.result = result;
+    }
+
+    /**
+     * Creates a new exception with the specified result, detail message and 
cause.
+     * 
+     * @param result The dependency result at the point the exception 
occurred, may be {@code null}.
+     * @param message The detail message, may be {@code null}.
+     * @param cause The exception that caused this one, may be {@code null}.
+     */
+    public DependencyResolutionException( DependencyResult result, String 
message, Throwable cause )
+    {
+        super( message, cause );
+        this.result = result;
+    }
+
+    private static String getMessage( Throwable cause )
+    {
+        String msg = null;
+        if ( cause != null )
+        {
+            msg = cause.getMessage();
+        }
+        if ( msg == null || msg.length() <= 0 )
+        {
+            msg = "Could not resolve transitive dependencies";
+        }
+        return msg;
+    }
+
+    /**
+     * Gets the dependency result at the point the exception occurred. Despite 
being incomplete, callers might want to
+     * use this result to fail gracefully and continue their operation with 
whatever interim data has been gathered.
+     * 
+     * @return The dependency result or {@code null} if unknown.
+     */
+    public DependencyResult getResult()
+    {
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResult.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResult.java
 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResult.java
new file mode 100644
index 0000000..030e923
--- /dev/null
+++ 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResult.java
@@ -0,0 +1,195 @@
+package org.eclipse.aether.resolution;
+
+/*
+ * 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.List;
+
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.graph.DependencyCycle;
+import org.eclipse.aether.graph.DependencyNode;
+
+/**
+ * The result of a dependency resolution request.
+ * 
+ * @see RepositorySystem#resolveDependencies(RepositorySystemSession, 
DependencyRequest)
+ */
+public final class DependencyResult
+{
+
+    private final DependencyRequest request;
+
+    private DependencyNode root;
+
+    private List<DependencyCycle> cycles;
+
+    private List<Exception> collectExceptions;
+
+    private List<ArtifactResult> artifactResults;
+
+    /**
+     * Creates a new result for the specified request.
+     * 
+     * @param request The resolution request, must not be {@code null}.
+     */
+    public DependencyResult( DependencyRequest request )
+    {
+        if ( request == null )
+        {
+            throw new IllegalArgumentException( "dependency request has not 
been specified" );
+        }
+        this.request = request;
+        root = request.getRoot();
+        cycles = Collections.emptyList();
+        collectExceptions = Collections.emptyList();
+        artifactResults = Collections.emptyList();
+    }
+
+    /**
+     * Gets the resolution request that was made.
+     * 
+     * @return The resolution request, never {@code null}.
+     */
+    public DependencyRequest getRequest()
+    {
+        return request;
+    }
+
+    /**
+     * Gets the root node of the resolved dependency graph. Note that this 
dependency graph might be
+     * incomplete/unfinished in case of {@link #getCollectExceptions()} 
indicating errors during its calculation.
+     * 
+     * @return The root node of the resolved dependency graph or {@code null} 
if none.
+     */
+    public DependencyNode getRoot()
+    {
+        return root;
+    }
+
+    /**
+     * Sets the root node of the resolved dependency graph.
+     * 
+     * @param root The root node of the resolved dependency graph, may be 
{@code null}.
+     * @return This result for chaining, never {@code null}.
+     */
+    public DependencyResult setRoot( DependencyNode root )
+    {
+        this.root = root;
+        return this;
+    }
+
+    /**
+     * Gets the dependency cycles that were encountered while building the 
dependency graph. Note that dependency cycles
+     * will only be reported here if the underlying request was created from a
+     * {@link org.eclipse.aether.collection.CollectRequest CollectRequest}. If 
the underlying {@link DependencyRequest}
+     * was created from an existing dependency graph, information about cycles 
will not be available in this result.
+     * 
+     * @return The dependency cycles in the (raw) graph, never {@code null}.
+     */
+    public List<DependencyCycle> getCycles()
+    {
+        return cycles;
+    }
+
+    /**
+     * Records the specified dependency cycles while building the dependency 
graph.
+     * 
+     * @param cycles The dependency cycles to record, may be {@code null}.
+     * @return This result for chaining, never {@code null}.
+     */
+    public DependencyResult setCycles( List<DependencyCycle> cycles )
+    {
+        if ( cycles == null )
+        {
+            this.cycles = Collections.emptyList();
+        }
+        else
+        {
+            this.cycles = cycles;
+        }
+        return this;
+    }
+
+    /**
+     * Gets the exceptions that occurred while building the dependency graph.
+     * 
+     * @return The exceptions that occurred, never {@code null}.
+     */
+    public List<Exception> getCollectExceptions()
+    {
+        return collectExceptions;
+    }
+
+    /**
+     * Records the specified exceptions while building the dependency graph.
+     * 
+     * @param exceptions The exceptions to record, may be {@code null}.
+     * @return This result for chaining, never {@code null}.
+     */
+    public DependencyResult setCollectExceptions( List<Exception> exceptions )
+    {
+        if ( exceptions == null )
+        {
+            this.collectExceptions = Collections.emptyList();
+        }
+        else
+        {
+            this.collectExceptions = exceptions;
+        }
+        return this;
+    }
+
+    /**
+     * Gets the resolution results for the dependency artifacts that matched 
{@link DependencyRequest#getFilter()}.
+     * 
+     * @return The resolution results for the dependency artifacts, never 
{@code null}.
+     */
+    public List<ArtifactResult> getArtifactResults()
+    {
+        return artifactResults;
+    }
+
+    /**
+     * Sets the resolution results for the artifacts that matched {@link 
DependencyRequest#getFilter()}.
+     * 
+     * @param results The resolution results for the artifacts, may be {@code 
null}.
+     * @return This result for chaining, never {@code null}.
+     */
+    public DependencyResult setArtifactResults( List<ArtifactResult> results )
+    {
+        if ( results == null )
+        {
+            this.artifactResults = Collections.emptyList();
+        }
+        else
+        {
+            this.artifactResults = results;
+        }
+        return this;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.valueOf( artifactResults );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataRequest.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataRequest.java
 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataRequest.java
new file mode 100644
index 0000000..86063ff
--- /dev/null
+++ 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataRequest.java
@@ -0,0 +1,232 @@
+package org.eclipse.aether.resolution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.metadata.Metadata;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * A request to resolve metadata from either a remote repository or the local 
repository.
+ * 
+ * @see RepositorySystem#resolveMetadata(RepositorySystemSession, 
java.util.Collection)
+ * @see Metadata#getFile()
+ */
+public final class MetadataRequest
+{
+
+    private Metadata metadata;
+
+    private RemoteRepository repository;
+
+    private String context = "";
+
+    private boolean deleteLocalCopyIfMissing;
+
+    private boolean favorLocalRepository;
+
+    private RequestTrace trace;
+
+    /**
+     * Creates an uninitialized request.
+     */
+    public MetadataRequest()
+    {
+        // enables default constructor
+    }
+
+    /**
+     * Creates a request to resolve the specified metadata from the local 
repository.
+     * 
+     * @param metadata The metadata to resolve, may be {@code null}.
+     */
+    public MetadataRequest( Metadata metadata )
+    {
+        setMetadata( metadata );
+    }
+
+    /**
+     * Creates a request with the specified properties.
+     * 
+     * @param metadata The metadata to resolve, may be {@code null}.
+     * @param repository The repository to resolve the metadata from, may be 
{@code null} to resolve from the local
+     *            repository.
+     * @param context The context in which this request is made, may be {@code 
null}.
+     */
+    public MetadataRequest( Metadata metadata, RemoteRepository repository, 
String context )
+    {
+        setMetadata( metadata );
+        setRepository( repository );
+        setRequestContext( context );
+    }
+
+    /**
+     * Gets the metadata to resolve.
+     * 
+     * @return The metadata or {@code null} if not set.
+     */
+    public Metadata getMetadata()
+    {
+        return metadata;
+    }
+
+    /**
+     * Sets the metadata to resolve.
+     * 
+     * @param metadata The metadata, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public MetadataRequest setMetadata( Metadata metadata )
+    {
+        this.metadata = metadata;
+        return this;
+    }
+
+    /**
+     * Gets the repository from which the metadata should be resolved.
+     * 
+     * @return The repository or {@code null} to resolve from the local 
repository.
+     */
+    public RemoteRepository getRepository()
+    {
+        return repository;
+    }
+
+    /**
+     * Sets the repository from which the metadata should be resolved.
+     * 
+     * @param repository The repository, may be {@code null} to resolve from 
the local repository.
+     * @return This request for chaining, never {@code null}.
+     */
+    public MetadataRequest setRepository( RemoteRepository repository )
+    {
+        this.repository = repository;
+        return this;
+    }
+
+    /**
+     * Gets the context in which this request is made.
+     * 
+     * @return The context, never {@code null}.
+     */
+    public String getRequestContext()
+    {
+        return context;
+    }
+
+    /**
+     * Sets the context in which this request is made.
+     * 
+     * @param context The context, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public MetadataRequest setRequestContext( String context )
+    {
+        this.context = ( context != null ) ? context : "";
+        return this;
+    }
+
+    /**
+     * Indicates whether the locally cached copy of the metadata should be 
removed if the corresponding file does not
+     * exist (any more) in the remote repository.
+     * 
+     * @return {@code true} if locally cached metadata should be deleted if no 
corresponding remote file exists,
+     *         {@code false} to keep the local copy.
+     */
+    public boolean isDeleteLocalCopyIfMissing()
+    {
+        return deleteLocalCopyIfMissing;
+    }
+
+    /**
+     * Controls whether the locally cached copy of the metadata should be 
removed if the corresponding file does not
+     * exist (any more) in the remote repository.
+     * 
+     * @param deleteLocalCopyIfMissing {@code true} if locally cached metadata 
should be deleted if no corresponding
+     *            remote file exists, {@code false} to keep the local copy.
+     * @return This request for chaining, never {@code null}.
+     */
+    public MetadataRequest setDeleteLocalCopyIfMissing( boolean 
deleteLocalCopyIfMissing )
+    {
+        this.deleteLocalCopyIfMissing = deleteLocalCopyIfMissing;
+        return this;
+    }
+
+    /**
+     * Indicates whether the metadata resolution should be suppressed if the 
corresponding metadata of the local
+     * repository is up-to-date according to the update policy of the remote 
repository. In this case, the metadata
+     * resolution will even be suppressed if no local copy of the remote 
metadata exists yet.
+     * 
+     * @return {@code true} to suppress resolution of remote metadata if the 
corresponding metadata of the local
+     *         repository is up-to-date, {@code false} to resolve the remote 
metadata normally according to the update
+     *         policy.
+     */
+    public boolean isFavorLocalRepository()
+    {
+        return favorLocalRepository;
+    }
+
+    /**
+     * Controls resolution of remote metadata when already corresponding 
metadata of the local repository exists. In
+     * cases where the local repository's metadata is sufficient and going to 
be preferred, resolution of the remote
+     * metadata can be suppressed to avoid unnecessary network access.
+     * 
+     * @param favorLocalRepository {@code true} to suppress resolution of 
remote metadata if the corresponding metadata
+     *            of the local repository is up-to-date, {@code false} to 
resolve the remote metadata normally according
+     *            to the update policy.
+     * @return This request for chaining, never {@code null}.
+     */
+    public MetadataRequest setFavorLocalRepository( boolean 
favorLocalRepository )
+    {
+        this.favorLocalRepository = favorLocalRepository;
+        return this;
+    }
+
+    /**
+     * Gets the trace information that describes the higher level 
request/operation in which this request is issued.
+     * 
+     * @return The trace information about the higher level operation or 
{@code null} if none.
+     */
+    public RequestTrace getTrace()
+    {
+        return trace;
+    }
+
+    /**
+     * Sets the trace information that describes the higher level 
request/operation in which this request is issued.
+     * 
+     * @param trace The trace information about the higher level operation, 
may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public MetadataRequest setTrace( RequestTrace trace )
+    {
+        this.trace = trace;
+        return this;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getMetadata() + " < " + getRepository();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataResult.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataResult.java
 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataResult.java
new file mode 100644
index 0000000..2bba499
--- /dev/null
+++ 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataResult.java
@@ -0,0 +1,166 @@
+package org.eclipse.aether.resolution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.metadata.Metadata;
+import org.eclipse.aether.transfer.MetadataNotFoundException;
+
+/**
+ * The result of a metadata resolution request.
+ * 
+ * @see RepositorySystem#resolveMetadata(RepositorySystemSession, 
java.util.Collection)
+ */
+public final class MetadataResult
+{
+
+    private final MetadataRequest request;
+
+    private Exception exception;
+
+    private boolean updated;
+
+    private Metadata metadata;
+
+    /**
+     * Creates a new result for the specified request.
+     * 
+     * @param request The resolution request, must not be {@code null}.
+     */
+    public MetadataResult( MetadataRequest request )
+    {
+        if ( request == null )
+        {
+            throw new IllegalArgumentException( "metadata request has not been 
specified" );
+        }
+        this.request = request;
+    }
+
+    /**
+     * Gets the resolution request that was made.
+     * 
+     * @return The resolution request, never {@code null}.
+     */
+    public MetadataRequest getRequest()
+    {
+        return request;
+    }
+
+    /**
+     * Gets the resolved metadata (if any).
+     * 
+     * @return The resolved metadata or {@code null} if the resolution failed.
+     */
+    public Metadata getMetadata()
+    {
+        return metadata;
+    }
+
+    /**
+     * Sets the resolved metadata.
+     * 
+     * @param metadata The resolved metadata, may be {@code null} if the 
resolution failed.
+     * @return This result for chaining, never {@code null}.
+     */
+    public MetadataResult setMetadata( Metadata metadata )
+    {
+        this.metadata = metadata;
+        return this;
+    }
+
+    /**
+     * Records the specified exception while resolving the metadata.
+     * 
+     * @param exception The exception to record, may be {@code null}.
+     * @return This result for chaining, never {@code null}.
+     */
+    public MetadataResult setException( Exception exception )
+    {
+        this.exception = exception;
+        return this;
+    }
+
+    /**
+     * Gets the exception that occurred while resolving the metadata.
+     * 
+     * @return The exception that occurred or {@code null} if none.
+     */
+    public Exception getException()
+    {
+        return exception;
+    }
+
+    /**
+     * Sets the updated flag for the metadata.
+     * 
+     * @param updated {@code true} if the metadata was actually fetched from 
the remote repository during the
+     *            resolution, {@code false} if the metadata was resolved from 
a locally cached copy.
+     * @return This result for chaining, never {@code null}.
+     */
+    public MetadataResult setUpdated( boolean updated )
+    {
+        this.updated = updated;
+        return this;
+    }
+
+    /**
+     * Indicates whether the metadata was actually fetched from the remote 
repository or resolved from the local cache.
+     * If metadata has been locally cached during a previous resolution 
request and this local copy is still up-to-date
+     * according to the remote repository's update policy, no remote access is 
made.
+     * 
+     * @return {@code true} if the metadata was actually fetched from the 
remote repository during the resolution,
+     *         {@code false} if the metadata was resolved from a locally 
cached copy.
+     */
+    public boolean isUpdated()
+    {
+        return updated;
+    }
+
+    /**
+     * Indicates whether the requested metadata was resolved. Note that the 
metadata might have been successfully
+     * resolved (from the local cache) despite {@link #getException()} 
indicating a transfer error while trying to
+     * refetch the metadata from the remote repository.
+     * 
+     * @return {@code true} if the metadata was resolved, {@code false} 
otherwise.
+     * @see Metadata#getFile()
+     */
+    public boolean isResolved()
+    {
+        return getMetadata() != null && getMetadata().getFile() != null;
+    }
+
+    /**
+     * Indicates whether the requested metadata is not present in the remote 
repository.
+     * 
+     * @return {@code true} if the metadata is not present in the remote 
repository, {@code false} otherwise.
+     */
+    public boolean isMissing()
+    {
+        return getException() instanceof MetadataNotFoundException;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getMetadata() + ( isUpdated() ? " (updated)" : " (cached)" );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicy.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicy.java
 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicy.java
new file mode 100644
index 0000000..5158fa0
--- /dev/null
+++ 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicy.java
@@ -0,0 +1,82 @@
+package org.eclipse.aether.resolution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.metadata.Metadata;
+
+/**
+ * Controls the caching of resolution errors for artifacts/metadata from 
remote repositories. If caching is enabled for
+ * a given resource, a marker will be set (usually somewhere in the local 
repository) to suppress repeated resolution
+ * attempts for the broken resource, thereby avoiding expensive but useless 
network IO. The error marker is considered
+ * stale once the repository's update policy has expired at which point a 
future resolution attempt will be allowed.
+ * Error caching considers the current network settings such that fixes to the 
configuration like authentication or
+ * proxy automatically trigger revalidation with the remote side regardless of 
the time elapsed since the previous
+ * resolution error.
+ * 
+ * @see RepositorySystemSession#getResolutionErrorPolicy()
+ */
+public interface ResolutionErrorPolicy
+{
+
+    /**
+     * Bit mask indicating that resolution errors should not be cached in the 
local repository. This forces the system
+     * to always query the remote repository for locally missing 
artifacts/metadata.
+     */
+    int CACHE_DISABLED = 0x00;
+
+    /**
+     * Bit flag indicating whether missing artifacts/metadata should be cached 
in the local repository. If caching is
+     * enabled, resolution will not be reattempted until the update policy for 
the affected resource has expired.
+     */
+    int CACHE_NOT_FOUND = 0x01;
+
+    /**
+     * Bit flag indicating whether connectivity/transfer errors (e.g. 
unreachable host, bad authentication) should be
+     * cached in the local repository. If caching is enabled, resolution will 
not be reattempted until the update policy
+     * for the affected resource has expired.
+     */
+    int CACHE_TRANSFER_ERROR = 0x02;
+
+    /**
+     * Bit mask indicating that all resolution errors should be cached in the 
local repository.
+     */
+    int CACHE_ALL = CACHE_NOT_FOUND | CACHE_TRANSFER_ERROR;
+
+    /**
+     * Gets the error policy for an artifact.
+     * 
+     * @param session The repository session during which the policy is 
determined, must not be {@code null}.
+     * @param request The policy request holding further details, must not be 
{@code null}.
+     * @return The bit mask describing the desired error policy.
+     */
+    int getArtifactPolicy( RepositorySystemSession session, 
ResolutionErrorPolicyRequest<Artifact> request );
+
+    /**
+     * Gets the error policy for some metadata.
+     * 
+     * @param session The repository session during which the policy is 
determined, must not be {@code null}.
+     * @param request The policy request holding further details, must not be 
{@code null}.
+     * @return The bit mask describing the desired error policy.
+     */
+    int getMetadataPolicy( RepositorySystemSession session, 
ResolutionErrorPolicyRequest<Metadata> request );
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicyRequest.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicyRequest.java
 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicyRequest.java
new file mode 100644
index 0000000..9126914
--- /dev/null
+++ 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicyRequest.java
@@ -0,0 +1,107 @@
+package org.eclipse.aether.resolution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * A query for the resolution error policy for a given artifact/metadata.
+ * 
+ * @param <T> The type of the affected repository item (artifact or metadata).
+ * @see ResolutionErrorPolicy
+ */
+public final class ResolutionErrorPolicyRequest<T>
+{
+
+    private T item;
+
+    private RemoteRepository repository;
+
+    /**
+     * Creates an uninitialized request.
+     */
+    public ResolutionErrorPolicyRequest()
+    {
+        // enables default constructor
+    }
+
+    /**
+     * Creates a request for the specified artifact/metadata and remote 
repository.
+     * 
+     * @param item The artifact/metadata for which to determine the error 
policy, may be {@code null}.
+     * @param repository The repository from which the resolution is 
attempted, may be {@code null}.
+     */
+    public ResolutionErrorPolicyRequest( T item, RemoteRepository repository )
+    {
+        setItem( item );
+        setRepository( repository );
+    }
+
+    /**
+     * Gets the artifact/metadata for which to determine the error policy.
+     * 
+     * @return The artifact/metadata for which to determine the error policy 
or {@code null} if not set.
+     */
+    public T getItem()
+    {
+        return item;
+    }
+
+    /**
+     * Sets the artifact/metadata for which to determine the error policy.
+     * 
+     * @param item The artifact/metadata for which to determine the error 
policy, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public ResolutionErrorPolicyRequest<T> setItem( T item )
+    {
+        this.item = item;
+        return this;
+    }
+
+    /**
+     * Gets the remote repository from which the resolution of the 
artifact/metadata is attempted.
+     * 
+     * @return The involved remote repository or {@code null} if not set.
+     */
+    public RemoteRepository getRepository()
+    {
+        return repository;
+    }
+
+    /**
+     * Sets the remote repository from which the resolution of the 
artifact/metadata is attempted.
+     * 
+     * @param repository The repository from which the resolution is 
attempted, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public ResolutionErrorPolicyRequest<T> setRepository( RemoteRepository 
repository )
+    {
+        this.repository = repository;
+        return this;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getItem() + " < " + getRepository();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeRequest.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeRequest.java
 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeRequest.java
new file mode 100644
index 0000000..d6aa16b
--- /dev/null
+++ 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeRequest.java
@@ -0,0 +1,190 @@
+package org.eclipse.aether.resolution;
+
+/*
+ * 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.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * A request to resolve a version range.
+ * 
+ * @see RepositorySystem#resolveVersionRange(RepositorySystemSession, 
VersionRangeRequest)
+ */
+public final class VersionRangeRequest
+{
+
+    private Artifact artifact;
+
+    private List<RemoteRepository> repositories = Collections.emptyList();
+
+    private String context = "";
+
+    private RequestTrace trace;
+
+    /**
+     * Creates an uninitialized request.
+     */
+    public VersionRangeRequest()
+    {
+        // enables default constructor
+    }
+
+    /**
+     * Creates a request with the specified properties.
+     * 
+     * @param artifact The artifact whose version range should be resolved, 
may be {@code null}.
+     * @param repositories The repositories to resolve the version from, may 
be {@code null}.
+     * @param context The context in which this request is made, may be {@code 
null}.
+     */
+    public VersionRangeRequest( Artifact artifact, List<RemoteRepository> 
repositories, String context )
+    {
+        setArtifact( artifact );
+        setRepositories( repositories );
+        setRequestContext( context );
+    }
+
+    /**
+     * Gets the artifact whose version range shall be resolved.
+     * 
+     * @return The artifact or {@code null} if not set.
+     */
+    public Artifact getArtifact()
+    {
+        return artifact;
+    }
+
+    /**
+     * Sets the artifact whose version range shall be resolved.
+     * 
+     * @param artifact The artifact, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public VersionRangeRequest setArtifact( Artifact artifact )
+    {
+        this.artifact = artifact;
+        return this;
+    }
+
+    /**
+     * Gets the repositories to resolve the version range from.
+     * 
+     * @return The repositories, never {@code null}.
+     */
+    public List<RemoteRepository> getRepositories()
+    {
+        return repositories;
+    }
+
+    /**
+     * Sets the repositories to resolve the version range from.
+     * 
+     * @param repositories The repositories, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public VersionRangeRequest setRepositories( List<RemoteRepository> 
repositories )
+    {
+        if ( repositories == null )
+        {
+            this.repositories = Collections.emptyList();
+        }
+        else
+        {
+            this.repositories = repositories;
+        }
+        return this;
+    }
+
+    /**
+     * Adds the specified repository for the resolution.
+     * 
+     * @param repository The repository to add, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public VersionRangeRequest addRepository( RemoteRepository repository )
+    {
+        if ( repository != null )
+        {
+            if ( this.repositories.isEmpty() )
+            {
+                this.repositories = new ArrayList<RemoteRepository>();
+            }
+            this.repositories.add( repository );
+        }
+        return this;
+    }
+
+    /**
+     * Gets the context in which this request is made.
+     * 
+     * @return The context, never {@code null}.
+     */
+    public String getRequestContext()
+    {
+        return context;
+    }
+
+    /**
+     * Sets the context in which this request is made.
+     * 
+     * @param context The context, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public VersionRangeRequest setRequestContext( String context )
+    {
+        this.context = ( context != null ) ? context : "";
+        return this;
+    }
+
+    /**
+     * Gets the trace information that describes the higher level 
request/operation in which this request is issued.
+     * 
+     * @return The trace information about the higher level operation or 
{@code null} if none.
+     */
+    public RequestTrace getTrace()
+    {
+        return trace;
+    }
+
+    /**
+     * Sets the trace information that describes the higher level 
request/operation in which this request is issued.
+     * 
+     * @param trace The trace information about the higher level operation, 
may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public VersionRangeRequest setTrace( RequestTrace trace )
+    {
+        this.trace = trace;
+        return this;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getArtifact() + " < " + getRepositories();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResolutionException.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResolutionException.java
 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResolutionException.java
new file mode 100644
index 0000000..deb0e52
--- /dev/null
+++ 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResolutionException.java
@@ -0,0 +1,105 @@
+package org.eclipse.aether.resolution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.RepositoryException;
+
+/**
+ * Thrown in case of an unparseable or unresolvable version range.
+ */
+public class VersionRangeResolutionException
+    extends RepositoryException
+{
+
+    private final transient VersionRangeResult result;
+
+    /**
+     * Creates a new exception with the specified result.
+     * 
+     * @param result The version range result at the point the exception 
occurred, may be {@code null}.
+     */
+    public VersionRangeResolutionException( VersionRangeResult result )
+    {
+        super( getMessage( result ), getCause( result ) );
+        this.result = result;
+    }
+
+    private static String getMessage( VersionRangeResult result )
+    {
+        StringBuilder buffer = new StringBuilder( 256 );
+        buffer.append( "Failed to resolve version range" );
+        if ( result != null )
+        {
+            buffer.append( " for " ).append( result.getRequest().getArtifact() 
);
+            if ( !result.getExceptions().isEmpty() )
+            {
+                buffer.append( ": " ).append( 
result.getExceptions().iterator().next().getMessage() );
+            }
+        }
+        return buffer.toString();
+    }
+
+    private static Throwable getCause( VersionRangeResult result )
+    {
+        Throwable cause = null;
+        if ( result != null && !result.getExceptions().isEmpty() )
+        {
+            cause = result.getExceptions().get( 0 );
+        }
+        return cause;
+    }
+
+    /**
+     * Creates a new exception with the specified result and detail message.
+     * 
+     * @param result The version range result at the point the exception 
occurred, may be {@code null}.
+     * @param message The detail message, may be {@code null}.
+     */
+    public VersionRangeResolutionException( VersionRangeResult result, String 
message )
+    {
+        super( message );
+        this.result = result;
+    }
+
+    /**
+     * Creates a new exception with the specified result, detail message and 
cause.
+     * 
+     * @param result The version range result at the point the exception 
occurred, may be {@code null}.
+     * @param message The detail message, may be {@code null}.
+     * @param cause The exception that caused this one, may be {@code null}.
+     */
+    public VersionRangeResolutionException( VersionRangeResult result, String 
message, Throwable cause )
+    {
+        super( message, cause );
+        this.result = result;
+    }
+
+    /**
+     * Gets the version range result at the point the exception occurred. 
Despite being incomplete, callers might want
+     * to use this result to fail gracefully and continue their operation with 
whatever interim data has been gathered.
+     * 
+     * @return The version range result or {@code null} if unknown.
+     */
+    public VersionRangeResult getResult()
+    {
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResult.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResult.java
 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResult.java
new file mode 100644
index 0000000..4749f7c
--- /dev/null
+++ 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResult.java
@@ -0,0 +1,240 @@
+package org.eclipse.aether.resolution;
+
+/*
+ * 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.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.ArtifactRepository;
+import org.eclipse.aether.version.Version;
+import org.eclipse.aether.version.VersionConstraint;
+
+/**
+ * The result of a version range resolution request.
+ * 
+ * @see RepositorySystem#resolveVersionRange(RepositorySystemSession, 
VersionRangeRequest)
+ */
+public final class VersionRangeResult
+{
+
+    private final VersionRangeRequest request;
+
+    private List<Exception> exceptions;
+
+    private List<Version> versions;
+
+    private Map<Version, ArtifactRepository> repositories;
+
+    private VersionConstraint versionConstraint;
+
+    /**
+     * Creates a new result for the specified request.
+     * 
+     * @param request The resolution request, must not be {@code null}.
+     */
+    public VersionRangeResult( VersionRangeRequest request )
+    {
+        if ( request == null )
+        {
+            throw new IllegalArgumentException( "version range request has not 
been specified" );
+        }
+        this.request = request;
+        exceptions = Collections.emptyList();
+        versions = Collections.emptyList();
+        repositories = Collections.emptyMap();
+    }
+
+    /**
+     * Gets the resolution request that was made.
+     * 
+     * @return The resolution request, never {@code null}.
+     */
+    public VersionRangeRequest getRequest()
+    {
+        return request;
+    }
+
+    /**
+     * Gets the exceptions that occurred while resolving the version range.
+     * 
+     * @return The exceptions that occurred, never {@code null}.
+     */
+    public List<Exception> getExceptions()
+    {
+        return exceptions;
+    }
+
+    /**
+     * Records the specified exception while resolving the version range.
+     * 
+     * @param exception The exception to record, may be {@code null}.
+     * @return This result for chaining, never {@code null}.
+     */
+    public VersionRangeResult addException( Exception exception )
+    {
+        if ( exception != null )
+        {
+            if ( exceptions.isEmpty() )
+            {
+                exceptions = new ArrayList<Exception>();
+            }
+            exceptions.add( exception );
+        }
+        return this;
+    }
+
+    /**
+     * Gets the versions (in ascending order) that matched the requested range.
+     * 
+     * @return The matching versions (if any), never {@code null}.
+     */
+    public List<Version> getVersions()
+    {
+        return versions;
+    }
+
+    /**
+     * Adds the specified version to the result. Note that versions must be 
added in ascending order.
+     * 
+     * @param version The version to add, must not be {@code null}.
+     * @return This result for chaining, never {@code null}.
+     */
+    public VersionRangeResult addVersion( Version version )
+    {
+        if ( versions.isEmpty() )
+        {
+            versions = new ArrayList<Version>();
+        }
+        versions.add( version );
+        return this;
+    }
+
+    /**
+     * Sets the versions (in ascending order) matching the requested range.
+     * 
+     * @param versions The matching versions, may be empty or {@code null} if 
none.
+     * @return This result for chaining, never {@code null}.
+     */
+    public VersionRangeResult setVersions( List<Version> versions )
+    {
+        if ( versions == null )
+        {
+            this.versions = Collections.emptyList();
+        }
+        else
+        {
+            this.versions = versions;
+        }
+        return this;
+    }
+
+    /**
+     * Gets the lowest version matching the requested range.
+     * 
+     * @return The lowest matching version or {@code null} if no versions 
matched the requested range.
+     */
+    public Version getLowestVersion()
+    {
+        if ( versions.isEmpty() )
+        {
+            return null;
+        }
+        return versions.get( 0 );
+    }
+
+    /**
+     * Gets the highest version matching the requested range.
+     * 
+     * @return The highest matching version or {@code null} if no versions 
matched the requested range.
+     */
+    public Version getHighestVersion()
+    {
+        if ( versions.isEmpty() )
+        {
+            return null;
+        }
+        return versions.get( versions.size() - 1 );
+    }
+
+    /**
+     * Gets the repository from which the specified version was resolved.
+     * 
+     * @param version The version whose source repository should be retrieved, 
must not be {@code null}.
+     * @return The repository from which the version was resolved or {@code 
null} if unknown.
+     */
+    public ArtifactRepository getRepository( Version version )
+    {
+        return repositories.get( version );
+    }
+
+    /**
+     * Records the repository from which the specified version was resolved
+     * 
+     * @param version The version whose source repository is to be recorded, 
must not be {@code null}.
+     * @param repository The repository from which the version was resolved, 
may be {@code null}.
+     * @return This result for chaining, never {@code null}.
+     */
+    public VersionRangeResult setRepository( Version version, 
ArtifactRepository repository )
+    {
+        if ( repository != null )
+        {
+            if ( repositories.isEmpty() )
+            {
+                repositories = new HashMap<Version, ArtifactRepository>();
+            }
+            repositories.put( version, repository );
+        }
+        return this;
+    }
+
+    /**
+     * Gets the version constraint that was parsed from the artifact's version 
string.
+     * 
+     * @return The parsed version constraint or {@code null}.
+     */
+    public VersionConstraint getVersionConstraint()
+    {
+        return versionConstraint;
+    }
+
+    /**
+     * Sets the version constraint that was parsed from the artifact's version 
string.
+     * 
+     * @param versionConstraint The parsed version constraint, may be {@code 
null}.
+     * @return This result for chaining, never {@code null}.
+     */
+    public VersionRangeResult setVersionConstraint( VersionConstraint 
versionConstraint )
+    {
+        this.versionConstraint = versionConstraint;
+        return this;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.valueOf( repositories );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRequest.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRequest.java
 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRequest.java
new file mode 100644
index 0000000..3dde7dd
--- /dev/null
+++ 
b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRequest.java
@@ -0,0 +1,190 @@
+package org.eclipse.aether.resolution;
+
+/*
+ * 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.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * A request to resolve a metaversion.
+ * 
+ * @see RepositorySystem#resolveVersion(RepositorySystemSession, 
VersionRequest)
+ */
+public final class VersionRequest
+{
+
+    private Artifact artifact;
+
+    private List<RemoteRepository> repositories = Collections.emptyList();
+
+    private String context = "";
+
+    private RequestTrace trace;
+
+    /**
+     * Creates an uninitialized request.
+     */
+    public VersionRequest()
+    {
+        // enables default constructor
+    }
+
+    /**
+     * Creates a request with the specified properties.
+     * 
+     * @param artifact The artifact whose (meta-)version should be resolved, 
may be {@code null}.
+     * @param repositories The repositories to resolve the version from, may 
be {@code null}.
+     * @param context The context in which this request is made, may be {@code 
null}.
+     */
+    public VersionRequest( Artifact artifact, List<RemoteRepository> 
repositories, String context )
+    {
+        setArtifact( artifact );
+        setRepositories( repositories );
+        setRequestContext( context );
+    }
+
+    /**
+     * Gets the artifact whose (meta-)version shall be resolved.
+     * 
+     * @return The artifact or {@code null} if not set.
+     */
+    public Artifact getArtifact()
+    {
+        return artifact;
+    }
+
+    /**
+     * Sets the artifact whose (meta-)version shall be resolved.
+     * 
+     * @param artifact The artifact, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public VersionRequest setArtifact( Artifact artifact )
+    {
+        this.artifact = artifact;
+        return this;
+    }
+
+    /**
+     * Gets the repositories to resolve the version from.
+     * 
+     * @return The repositories, never {@code null}.
+     */
+    public List<RemoteRepository> getRepositories()
+    {
+        return repositories;
+    }
+
+    /**
+     * Sets the repositories to resolve the version from.
+     * 
+     * @param repositories The repositories, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public VersionRequest setRepositories( List<RemoteRepository> repositories 
)
+    {
+        if ( repositories == null )
+        {
+            this.repositories = Collections.emptyList();
+        }
+        else
+        {
+            this.repositories = repositories;
+        }
+        return this;
+    }
+
+    /**
+     * Adds the specified repository for the resolution.
+     * 
+     * @param repository The repository to add, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public VersionRequest addRepository( RemoteRepository repository )
+    {
+        if ( repository != null )
+        {
+            if ( this.repositories.isEmpty() )
+            {
+                this.repositories = new ArrayList<RemoteRepository>();
+            }
+            this.repositories.add( repository );
+        }
+        return this;
+    }
+
+    /**
+     * Gets the context in which this request is made.
+     * 
+     * @return The context, never {@code null}.
+     */
+    public String getRequestContext()
+    {
+        return context;
+    }
+
+    /**
+     * Sets the context in which this request is made.
+     * 
+     * @param context The context, may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public VersionRequest setRequestContext( String context )
+    {
+        this.context = ( context != null ) ? context : "";
+        return this;
+    }
+
+    /**
+     * Gets the trace information that describes the higher level 
request/operation in which this request is issued.
+     * 
+     * @return The trace information about the higher level operation or 
{@code null} if none.
+     */
+    public RequestTrace getTrace()
+    {
+        return trace;
+    }
+
+    /**
+     * Sets the trace information that describes the higher level 
request/operation in which this request is issued.
+     * 
+     * @param trace The trace information about the higher level operation, 
may be {@code null}.
+     * @return This request for chaining, never {@code null}.
+     */
+    public VersionRequest setTrace( RequestTrace trace )
+    {
+        this.trace = trace;
+        return this;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getArtifact() + " < " + getRepositories();
+    }
+
+}

Reply via email to