1   package org.apache.maven.artifact.resolver;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.artifact.Artifact;
23  import org.apache.maven.artifact.factory.ArtifactFactory;
24  import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
25  import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
26  import org.apache.maven.artifact.metadata.ResolutionGroup;
27  import org.apache.maven.artifact.repository.ArtifactRepository;
28  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
29  import org.apache.maven.artifact.resolver.filter.ExclusionSetFilter;
30  import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
31  import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
32  import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
33  import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
34  import org.apache.maven.artifact.versioning.VersionRange;
35  import org.codehaus.plexus.PlexusTestCase;
36  
37  import java.util.ArrayList;
38  import java.util.Arrays;
39  import java.util.Collections;
40  import java.util.HashMap;
41  import java.util.HashSet;
42  import java.util.Iterator;
43  import java.util.LinkedHashSet;
44  import java.util.List;
45  import java.util.Map;
46  import java.util.Set;
47  
48  /**
49   * Test the default artifact collector.
50   *
51   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
52   * @version $Id: DefaultArtifactCollectorTest.java 675087 2008-07-09 02:23:29Z jdcasey $
53   */
54  public class DefaultArtifactCollectorTest
55      extends PlexusTestCase
56  {
57      private ArtifactCollector artifactCollector;
58  
59      private ArtifactFactory artifactFactory;
60  
61      private ArtifactSpec projectArtifact;
62  
63      private Source source;
64  
65      private static final String GROUP_ID = "test";
66  
67      protected void setUp()
68          throws Exception
69      {
70          super.setUp();
71  
72          source = new Source();
73          artifactFactory = (ArtifactFactory) lookup( ArtifactFactory.ROLE );
74          artifactCollector = new DefaultArtifactCollector();
75  
76          projectArtifact = createArtifactSpec( "project", "1.0", null );
77      }
78  
79      // works, but we don't fail on cycles presently
80      public void disabledtestCircularDependencyNotIncludingCurrentProject()
81          throws ArtifactResolutionException, InvalidVersionSpecificationException
82      {
83          ArtifactSpec a = createArtifactSpec( "a", "1.0" );
84          ArtifactSpec b = a.addDependency( "b", "1.0" );
85          b.addDependency( "a", "1.0" );
86          try
87          {
88              collect( a );
89              fail( "Should have failed on cyclic dependency not involving project" );
90          }
91          catch ( CyclicDependencyException expected )
92          {
93              assertTrue( true );
94          }
95      }
96  
97      // works, but we don't fail on cycles presently
98      public void disabledtestCircularDependencyIncludingCurrentProject()
99          throws ArtifactResolutionException, InvalidVersionSpecificationException
100     {
101         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
102         ArtifactSpec b = a.addDependency( "b", "1.0" );
103         b.addDependency( "project", "1.0" );
104         try
105         {
106             collect( a );
107             fail( "Should have failed on cyclic dependency involving project" );
108         }
109         catch ( CyclicDependencyException expected )
110         {
111             assertTrue( true );
112         }
113     }
114 
115     public void testResolveWithFilter()
116         throws ArtifactResolutionException, InvalidVersionSpecificationException
117     {
118         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
119         ArtifactSpec b = a.addDependency( "b", "1.0" );
120         ArtifactSpec c = a.addDependency( "c", "3.0" );
121 
122         b.addDependency( "c", "2.0" );
123         ArtifactSpec d = b.addDependency( "d", "4.0" );
124 
125         ArtifactResolutionResult res = collect( a );
126         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact, c.artifact, d.artifact} ),
127                       res.getArtifacts() );
128 
129         ArtifactFilter filter = new ExclusionSetFilter( new String[]{"b"} );
130         res = collect( a, filter );
131         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, c.artifact} ), res.getArtifacts() );
132     }
133 
134     public void testResolveCorrectDependenciesWhenDifferentDependenciesOnNearest()
135         throws ArtifactResolutionException, InvalidVersionSpecificationException
136     {
137         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
138         ArtifactSpec b = a.addDependency( "b", "1.0" );
139         ArtifactSpec c2 = b.addDependency( "c", "2.0" );
140         c2.addDependency( "d", "1.0" );
141 
142         ArtifactSpec e = createArtifactSpec( "e", "1.0" );
143         ArtifactSpec c1 = e.addDependency( "c", "1.0" );
144         ArtifactSpec f = c1.addDependency( "f", "1.0" );
145 
146         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, e.artifact} ) );
147         assertEquals( "Check artifact list",
148                       createSet( new Object[]{a.artifact, b.artifact, e.artifact, c1.artifact, f.artifact} ),
149                       res.getArtifacts() );
150         assertEquals( "Check version", "1.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
151     }
152 
153     public void disabledtestResolveCorrectDependenciesWhenDifferentDependenciesOnNewest()
154         throws ArtifactResolutionException, InvalidVersionSpecificationException
155     {
156         // TODO: use newest conflict resolver
157         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
158         ArtifactSpec b = a.addDependency( "b", "1.0" );
159         ArtifactSpec c2 = b.addDependency( "c", "2.0" );
160         ArtifactSpec d = c2.addDependency( "d", "1.0" );
161 
162         ArtifactSpec e = createArtifactSpec( "e", "1.0" );
163         ArtifactSpec c1 = e.addDependency( "c", "1.0" );
164         c1.addDependency( "f", "1.0" );
165 
166         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, e.artifact} ) );
167         assertEquals( "Check artifact list",
168                       createSet( new Object[]{a.artifact, b.artifact, e.artifact, c2.artifact, d.artifact} ),
169                       res.getArtifacts() );
170         assertEquals( "Check version", "2.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
171     }
172 
173     public void disabledtestResolveCorrectDependenciesWhenDifferentDependenciesOnNewestVersionReplaced()
174         throws ArtifactResolutionException, InvalidVersionSpecificationException
175     {
176         // TODO: use newest conflict resolver
177         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
178         ArtifactSpec b1 = a.addDependency( "b", "1.0" );
179         ArtifactSpec c = a.addDependency( "c", "1.0" );
180         ArtifactSpec d2 = b1.addDependency( "d", "2.0" );
181         d2.addDependency( "h", "1.0" );
182         ArtifactSpec d1 = c.addDependency( "d", "1.0" );
183         ArtifactSpec b2 = c.addDependency( "b", "2.0" );
184         ArtifactSpec e = b2.addDependency( "e", "1.0" );
185         ArtifactSpec g = d1.addDependency( "g", "1.0" );
186 
187         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact} ) );
188         Object[] artifacts = new Object[]{a.artifact, c.artifact, d1.artifact, b2.artifact, e.artifact, g.artifact};
189         assertEquals( "Check artifact list", createSet( artifacts ), res.getArtifacts() );
190         assertEquals( "Check version", "1.0", getArtifact( "d", res.getArtifacts() ).getVersion() );
191         assertEquals( "Check version", "2.0", getArtifact( "b", res.getArtifacts() ).getVersion() );
192     }
193 
194     public void testResolveNearestNewestIsNearest()
195         throws ArtifactResolutionException, InvalidVersionSpecificationException
196     {
197         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
198         ArtifactSpec b = a.addDependency( "b", "1.0" );
199         ArtifactSpec c = a.addDependency( "c", "3.0" );
200 
201         b.addDependency( "c", "2.0" );
202 
203         ArtifactResolutionResult res = collect( a );
204         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact, c.artifact} ),
205                       res.getArtifacts() );
206         assertEquals( "Check version", "3.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
207     }
208 
209     public void testResolveNearestOldestIsNearest()
210         throws ArtifactResolutionException, InvalidVersionSpecificationException
211     {
212         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
213         ArtifactSpec b = a.addDependency( "b", "1.0" );
214         ArtifactSpec c = a.addDependency( "c", "2.0" );
215 
216         b.addDependency( "c", "3.0" );
217 
218         ArtifactResolutionResult res = collect( a );
219         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact, c.artifact} ),
220                       res.getArtifacts() );
221         assertEquals( "Check version", "2.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
222     }
223 
224     public void testResolveLocalNewestIsLocal()
225         throws ArtifactResolutionException, InvalidVersionSpecificationException
226     {
227         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
228         a.addDependency( "b", "2.0" );
229         ArtifactSpec b = createArtifactSpec( "b", "3.0" );
230 
231         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, b.artifact} ) );
232         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact} ), res.getArtifacts() );
233         assertEquals( "Check version", "3.0", getArtifact( "b", res.getArtifacts() ).getVersion() );
234     }
235 
236     public void testResolveLocalOldestIsLocal()
237         throws ArtifactResolutionException, InvalidVersionSpecificationException
238     {
239         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
240         a.addDependency( "b", "3.0" );
241         ArtifactSpec b = createArtifactSpec( "b", "2.0" );
242 
243         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, b.artifact} ) );
244         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact} ), res.getArtifacts() );
245         assertEquals( "Check version", "2.0", getArtifact( "b", res.getArtifacts() ).getVersion() );
246     }
247 
248     public void testResolveLocalWithNewerVersionButLesserScope()
249         throws ArtifactResolutionException, InvalidVersionSpecificationException
250     {
251         ArtifactSpec a = createArtifactSpec( "commons-logging", "1.0" );
252         a.addDependency( "junit", "3.7" );
253         ArtifactSpec b = createArtifactSpec( "junit", "3.8.1", Artifact.SCOPE_TEST );
254 
255         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, b.artifact} ) );
256         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact} ), res.getArtifacts() );
257         assertEquals( "Check version", "3.8.1", getArtifact( "junit", res.getArtifacts() ).getVersion() );
258         assertEquals( "Check scope", Artifact.SCOPE_TEST, getArtifact( "junit", res.getArtifacts() ).getScope() );
259     }
260 
261     public void testResolveLocalWithNewerVersionButLesserScopeResolvedFirst()
262         throws ArtifactResolutionException, InvalidVersionSpecificationException
263     {
264         ArtifactSpec b = createArtifactSpec( "junit", "3.8.1", Artifact.SCOPE_TEST );
265         ArtifactSpec a = createArtifactSpec( "commons-logging", "1.0" );
266         a.addDependency( "junit", "3.7" );
267 
268         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, b.artifact} ) );
269         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact} ), res.getArtifacts() );
270         assertEquals( "Check version", "3.8.1", getArtifact( "junit", res.getArtifacts() ).getVersion() );
271         assertEquals( "Check scope", Artifact.SCOPE_TEST, getArtifact( "junit", res.getArtifacts() ).getScope() );
272     }
273 
274     public void testResolveNearestWithRanges()
275         throws ArtifactResolutionException, InvalidVersionSpecificationException
276     {
277         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
278         ArtifactSpec b = a.addDependency( "b", "1.0" );
279         ArtifactSpec c = a.addDependency( "c", "2.0" );
280 
281         b.addDependency( "c", "[1.0,3.0]" );
282 
283         ArtifactResolutionResult res = collect( a );
284         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact, c.artifact} ),
285                       res.getArtifacts() );
286         assertEquals( "Check version", "2.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
287     }
288 
289     public void testResolveRangeWithManagedVersion()
290         throws ArtifactResolutionException, InvalidVersionSpecificationException
291     {
292         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
293         ArtifactSpec b = a.addDependency( "b", "[1.0,3.0]" );
294 
295         ArtifactSpec managedB = createArtifactSpec( "b", "5.0" );
296 
297         ArtifactResolutionResult res = collect( a, managedB.artifact );
298         assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, managedB.artifact } ),
299                       res.getArtifacts() );
300         assertEquals( "Check version", "5.0", getArtifact( "b", res.getArtifacts() ).getVersion() );
301     }
302 
303     public void testCompatibleRanges()
304         throws ArtifactResolutionException, InvalidVersionSpecificationException
305     {
306         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
307         ArtifactSpec b = a.addDependency( "b", "1.0" );
308         a.addDependency( "c", "[2.0,2.5]" );
309         b.addDependency( "c", "[1.0,3.0]" );
310         ArtifactSpec c = createArtifactSpec( "c", "2.5" );
311 
312         ArtifactResolutionResult res = collect( a );
313 
314         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact, c.artifact} ),
315                       res.getArtifacts() );
316         assertEquals( "Check version", "2.5", getArtifact( "c", res.getArtifacts() ).getVersion() );
317     }
318 
319     public void testCompatibleRecommendedVersion()
320         throws ArtifactResolutionException, InvalidVersionSpecificationException
321     {
322 
323         //this test puts two dependencies on C with 3.2 and [1.0,3.0] as the version.
324         //it puts 2.5 in the pretend repo...we should get back 2.5
325         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
326         ArtifactSpec b = a.addDependency( "b", "1.0" );
327         ArtifactSpec b1 = a.addDependency( "b1", "1.0" );
328         b.addDependency( "c", "3.2" );
329         b1.addDependency( "c", "[1.0,3.0]" );
330 
331         //put it in the repo
332         ArtifactSpec c = createArtifactSpec( "c", "2.5" );
333         source.addArtifact( createArtifactSpec( "c", "2.5" ));
334 
335         ArtifactResolutionResult res = collect( a );
336 
337         assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact,b1.artifact,c.artifact } ),
338                       res.getArtifacts() );
339         assertEquals( "Check version", "2.5", getArtifact( "c", res.getArtifacts() ).getVersion() );
340     }
341 
342     public void testCompatibleRecommendedVersionWithChildren()
343         throws ArtifactResolutionException, InvalidVersionSpecificationException
344     {
345 
346         // this test puts two dependencies on C with 3.2 and [1.0,3.0] as the version.
347         // it puts 2.5 in the pretend repo...we should get back c2.5 and d1.0
348         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
349         ArtifactSpec b = a.addDependency( "b", "1.0" );
350         ArtifactSpec e = a.addDependency( "e", "1.0" );
351         ArtifactSpec c1 = b.addDependency( "c", "3.2" );
352         ArtifactSpec d1 = c1.addDependency( "d","1.1" );
353         e.addDependency( "c", "[1.0,3.0]" );
354 
355         // put it in the repo
356         ArtifactSpec c = createArtifactSpec( "c", "2.5" );
357         ArtifactSpec d = c.addDependency( "d","1.0" );
358 
359         source.addArtifact( c );
360         source.addArtifact( d );
361         source.addArtifact( c1 );
362         source.addArtifact( d1 );
363 
364         ArtifactResolutionResult res = collect( a );
365 
366         assertEquals( "Check artifact list",
367                       createSet( new Object[] { a.artifact, b.artifact, e.artifact, c.artifact,d.artifact } ), res.getArtifacts() );
368         assertEquals( "Check version", "2.5", getArtifact( "c", res.getArtifacts() ).getVersion() );
369     }
370 
371     public void testInCompatibleRecommendedVersion()
372         throws ArtifactResolutionException, InvalidVersionSpecificationException
373     {
374 
375         // this test puts two dependencies on C with 3.2 and [1.0,3.0] as the version.
376         // it puts 2.5 and 3.0 in the pretend repo...we should get back 3.0
377         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
378         ArtifactSpec b = a.addDependency( "b", "1.0" );
379         ArtifactSpec b1 = a.addDependency( "b1", "1.0" );
380         b.addDependency( "c", "3.2" );
381         b1.addDependency( "c", "[1.0,3.0]" );
382 
383         // put it in the repo
384         ArtifactSpec c = createArtifactSpec( "c", "3.0" );
385         source.addArtifact( createArtifactSpec( "c", "2.5" ) );
386         source.addArtifact( createArtifactSpec( "c", "3.0" ) );
387         source.addArtifact( createArtifactSpec( "c", "3.2" ) );
388 
389         ArtifactResolutionResult res = collect( a );
390 
391         assertEquals( "Check artifact list",
392                       createSet( new Object[] { a.artifact, b.artifact, b1.artifact, c.artifact } ), res.getArtifacts() );
393         assertEquals( "Check version", "3.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
394     }
395 
396     //MNG-2123: this version of the test caused the crash seen in the IT. It was
397     //only happening if the first dependency was not a range but the second one was.
398     public void testInCompatibleRecommendedVersion2()
399         throws ArtifactResolutionException, InvalidVersionSpecificationException
400     {
401 
402         // this test puts two dependencies on C with 3.2 and [1.0,3.0] as the version.
403         // it puts 2.5 and 3.0 in the pretend repo...we should get back 3.0
404         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
405         ArtifactSpec b = a.addDependency( "b", "1.0" );
406         ArtifactSpec b1 = a.addDependency( "b1", "1.0" );
407         b1.addDependency( "c", "3.2" );
408         b.addDependency( "c", "[1.0,3.0]" );
409 
410         // put it in the repo
411         ArtifactSpec c = createArtifactSpec( "c", "3.0" );
412         source.addArtifact( createArtifactSpec( "c", "2.5" ) );
413         source.addArtifact( createArtifactSpec( "c", "3.0" ) );
414         source.addArtifact( createArtifactSpec( "c", "3.2" ) );
415 
416         ArtifactResolutionResult res = collect( a );
417 
418         assertEquals( "Check artifact list",
419                       createSet( new Object[] { a.artifact, b.artifact, b1.artifact, c.artifact } ), res.getArtifacts() );
420         assertEquals( "Check version", "3.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
421     }
422 
423     public void testIncompatibleRanges()
424         throws ArtifactResolutionException, InvalidVersionSpecificationException
425     {
426         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
427         ArtifactSpec b = a.addDependency( "b", "1.0" );
428         a.addDependency( "c", "[2.4,3.0]" );
429 
430         b.addDependency( "c", "[1.0,2.0]" );
431 
432         try
433         {
434             ArtifactResolutionResult res = collect( a );
435             fail( "Should not succeed collecting, got: " + res.getArtifacts() );
436         }
437         catch ( ArtifactResolutionException expected )
438         {
439         }
440     }
441 
442     public void testUnboundedRangeWhenVersionUnavailable()
443         throws ArtifactResolutionException, InvalidVersionSpecificationException
444     {
445         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
446         ArtifactSpec b = a.addDependency( "b", "1.0" );
447         a.addDependency( "c", "[2.0,]" );
448         b.addDependency( "c", "[1.0,]" );
449 
450         try
451         {
452             ArtifactResolutionResult res = collect( a );
453             fail( "Should not succeed collecting, got: " + res.getArtifacts() );
454         }
455         catch ( ArtifactResolutionException expected )
456         {
457             assertTrue( true );
458         }
459     }
460 
461     public void testUnboundedRangeBelowLastRelease()
462         throws ArtifactResolutionException, InvalidVersionSpecificationException
463     {
464         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
465         createArtifactSpec( "c", "1.5" );
466         ArtifactSpec c = createArtifactSpec( "c", "2.0" );
467         createArtifactSpec( "c", "1.1" );
468         a.addDependency( "c", "[1.0,)" );
469 
470         ArtifactResolutionResult res = collect( a );
471 
472         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, c.artifact} ), res.getArtifacts() );
473         assertEquals( "Check version", "2.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
474     }
475 
476     public void testUnboundedRangeAboveLastRelease()
477         throws ArtifactResolutionException, InvalidVersionSpecificationException
478     {
479         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
480         createArtifactSpec( "c", "2.0" );
481         a.addDependency( "c", "[10.0,)" );
482 
483         try
484         {
485             ArtifactResolutionResult res = collect( a );
486             fail( "Should not succeed collecting, got: " + res.getArtifacts() );
487         }
488         catch ( ArtifactResolutionException expected )
489         {
490             assertTrue( true );
491         }
492     }
493 
494     public void testResolveManagedVersion()
495         throws ArtifactResolutionException, InvalidVersionSpecificationException
496     {
497         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
498         a.addDependency( "b", "3.0", Artifact.SCOPE_RUNTIME );
499 
500         Artifact managedVersion = createArtifactSpec( "b", "5.0" ).artifact;
501         Artifact modifiedB = createArtifactSpec( "b", "5.0", Artifact.SCOPE_RUNTIME ).artifact;
502 
503         ArtifactResolutionResult res = collect( a, managedVersion );
504         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, modifiedB} ), res.getArtifacts() );
505     }
506 
507     public void testCollectChangesVersionOfOriginatingArtifactIfInDependencyManagementHasDifferentVersion()
508         throws ArtifactResolutionException, InvalidVersionSpecificationException
509     {
510         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
511 
512         Artifact artifact = projectArtifact.artifact;
513         Artifact managedVersion = createArtifactSpec( artifact.getArtifactId(), "2.0" ).artifact;
514 
515         ArtifactResolutionResult result = collect( a, managedVersion );
516 
517         assertEquals( "collect has modified version in originating artifact", "1.0", artifact.getVersion() );
518 
519         Artifact resolvedArtifact = (Artifact) result.getArtifacts().iterator().next();
520 
521         assertEquals( "Resolved version don't match original artifact version", "1.0", resolvedArtifact.getVersion() );
522     }
523 
524     public void testResolveCompileScopeOverTestScope()
525         throws ArtifactResolutionException, InvalidVersionSpecificationException
526     {
527         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
528         ArtifactSpec c = createArtifactSpec( "c", "3.0", Artifact.SCOPE_TEST );
529 
530         a.addDependency( "c", "2.0", Artifact.SCOPE_COMPILE );
531 
532         Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_COMPILE ).artifact;
533 
534         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, c.artifact} ) );
535         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, modifiedC} ), res.getArtifacts() );
536         Artifact artifact = getArtifact( "c", res.getArtifacts() );
537         // local wins now, and irrelevant if not local as test/provided aren't transitive
538 //        assertEquals( "Check scope", Artifact.SCOPE_COMPILE, artifact.getScope() );
539         assertEquals( "Check scope", Artifact.SCOPE_TEST, artifact.getScope() );
540     }
541 
542     public void testResolveRuntimeScopeOverTestScope()
543         throws ArtifactResolutionException, InvalidVersionSpecificationException
544     {
545         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
546         ArtifactSpec c = createArtifactSpec( "c", "3.0", Artifact.SCOPE_TEST );
547 
548         a.addDependency( "c", "2.0", Artifact.SCOPE_RUNTIME );
549 
550         Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_RUNTIME ).artifact;
551 
552         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, c.artifact} ) );
553         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, modifiedC} ), res.getArtifacts() );
554         Artifact artifact = getArtifact( "c", res.getArtifacts() );
555         // local wins now, and irrelevant if not local as test/provided aren't transitive
556 //        assertEquals( "Check scope", Artifact.SCOPE_RUNTIME, artifact.getScope() );
557         assertEquals( "Check scope", Artifact.SCOPE_TEST, artifact.getScope() );
558     }
559 
560     public void testResolveCompileScopeOverRuntimeScope()
561         throws ArtifactResolutionException, InvalidVersionSpecificationException
562     {
563         ArtifactSpec root = createArtifactSpec( "root", "1.0" );
564         ArtifactSpec a = root.addDependency( "a", "1.0" );
565         root.addDependency( "c", "3.0", Artifact.SCOPE_RUNTIME );
566 
567         a.addDependency( "c", "2.0", Artifact.SCOPE_COMPILE );
568 
569         Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_COMPILE ).artifact;
570 
571         ArtifactResolutionResult res = collect( createSet( new Object[]{root.artifact} ) );
572         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, root.artifact, modifiedC} ),
573                       res.getArtifacts() );
574         Artifact artifact = getArtifact( "c", res.getArtifacts() );
575         assertEquals( "Check scope", Artifact.SCOPE_COMPILE, artifact.getScope() );
576     }
577 
578     public void testResolveCompileScopeOverProvidedScope()
579         throws ArtifactResolutionException, InvalidVersionSpecificationException
580     {
581         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
582         ArtifactSpec c = createArtifactSpec( "c", "3.0", Artifact.SCOPE_PROVIDED );
583 
584         a.addDependency( "c", "2.0", Artifact.SCOPE_COMPILE );
585 
586         Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_COMPILE ).artifact;
587 
588         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, c.artifact} ) );
589         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, modifiedC} ), res.getArtifacts() );
590         Artifact artifact = getArtifact( "c", res.getArtifacts() );
591         // local wins now, and irrelevant if not local as test/provided aren't transitive
592 //        assertEquals( "Check scope", Artifact.SCOPE_COMPILE, artifact.getScope() );
593         assertEquals( "Check scope", Artifact.SCOPE_PROVIDED, artifact.getScope() );
594     }
595 
596     public void testResolveRuntimeScopeOverProvidedScope()
597         throws ArtifactResolutionException, InvalidVersionSpecificationException
598     {
599         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
600         ArtifactSpec c = createArtifactSpec( "c", "3.0", Artifact.SCOPE_PROVIDED );
601 
602         a.addDependency( "c", "2.0", Artifact.SCOPE_RUNTIME );
603 
604         Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_RUNTIME ).artifact;
605 
606         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, c.artifact} ) );
607         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, modifiedC} ), res.getArtifacts() );
608         Artifact artifact = getArtifact( "c", res.getArtifacts() );
609         // local wins now, and irrelevant if not local as test/provided aren't transitive
610 //        assertEquals( "Check scope", Artifact.SCOPE_RUNTIME, artifact.getScope() );
611         assertEquals( "Check scope", Artifact.SCOPE_PROVIDED, artifact.getScope() );
612     }
613 
614     public void testProvidedScopeNotTransitive()
615         throws ArtifactResolutionException, InvalidVersionSpecificationException
616     {
617         ArtifactSpec a = createArtifactSpec( "a", "1.0", Artifact.SCOPE_PROVIDED );
618         ArtifactSpec b = createArtifactSpec( "b", "1.0" );
619         b.addDependency( "c", "3.0", Artifact.SCOPE_PROVIDED );
620 
621         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, b.artifact} ) );
622         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact} ), res.getArtifacts() );
623     }
624 
625     public void testOptionalNotTransitive()
626         throws ArtifactResolutionException, InvalidVersionSpecificationException
627     {
628         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
629         ArtifactSpec b = createArtifactSpec( "b", "1.0" );
630         b.addDependency( "c", "3.0", true );
631 
632         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, b.artifact} ) );
633         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact} ), res.getArtifacts() );
634     }
635 
636     public void testOptionalIncludedAtRoot()
637         throws ArtifactResolutionException, InvalidVersionSpecificationException
638     {
639         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
640 
641         ArtifactSpec b = createArtifactSpec( "b", "1.0", true );
642 
643         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, b.artifact} ) );
644         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact} ), res.getArtifacts() );
645     }
646 
647     public void testScopeUpdate()
648         throws InvalidVersionSpecificationException, ArtifactResolutionException
649     {
650         /* farthest = compile */
651         checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE );
652         checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_COMPILE );
653         checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_COMPILE );
654         checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_COMPILE );
655         checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_TEST, Artifact.SCOPE_COMPILE );
656 
657         /* farthest = provided */
658         checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE );
659         checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED );
660         checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME );
661         checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM );
662         checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST );
663 
664         /* farthest = runtime */
665         checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE );
666         checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_RUNTIME );
667         checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME );
668         checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM );
669         checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_TEST, Artifact.SCOPE_RUNTIME );
670 
671         /* farthest = system */
672         checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE );
673         checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED );
674         checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME );
675         checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM );
676         checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST );
677 
678         /* farthest = test */
679         checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE );
680         checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED );
681         checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME );
682         checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM );
683         checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST );
684     }
685 
686     private void checkScopeUpdate( String farthestScope, String nearestScope, String expectedScope )
687         throws ArtifactResolutionException, InvalidVersionSpecificationException
688     {
689         checkScopeUpdateDirect( farthestScope, nearestScope, expectedScope );
690         checkScopeUpdateTransitively( farthestScope, nearestScope, expectedScope );
691     }
692 
693     private void checkScopeUpdateTransitively( String farthestScope, String nearestScope, String expectedScope )
694         throws ArtifactResolutionException, InvalidVersionSpecificationException
695     {
696         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
697         ArtifactSpec b = createArtifactSpec( "b", "1.0", nearestScope );
698         ArtifactSpec c = createArtifactSpec( "c", "1.0" );
699         a.addDependency( c );
700         ArtifactSpec dNearest = createArtifactSpec( "d", "2.0" );
701         b.addDependency( dNearest );
702         ArtifactSpec dFarthest = createArtifactSpec( "d", "3.0", farthestScope );
703         c.addDependency( dFarthest );
704 
705         /* system and provided dependencies are not transitive */
706         if ( !Artifact.SCOPE_SYSTEM.equals( nearestScope ) && !Artifact.SCOPE_PROVIDED.equals( nearestScope ) )
707         {
708             checkScopeUpdate( a, b, expectedScope, "2.0" );
709         }
710     }
711 
712     private void checkScopeUpdateDirect( String farthestScope, String nearestScope, String expectedScope )
713         throws ArtifactResolutionException, InvalidVersionSpecificationException
714     {
715         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
716         ArtifactSpec b = createArtifactSpec( "b", "1.0" );
717         ArtifactSpec c = createArtifactSpec( "c", "1.0" );
718         a.addDependency( c );
719         ArtifactSpec dNearest = createArtifactSpec( "d", "2.0", nearestScope );
720         b.addDependency( dNearest );
721         ArtifactSpec dFarthest = createArtifactSpec( "d", "3.0", farthestScope );
722         c.addDependency( dFarthest );
723 
724         checkScopeUpdate( a, b, expectedScope, "2.0" );
725     }
726 
727     private void checkScopeUpdate( ArtifactSpec a, ArtifactSpec b, String expectedScope, String expectedVersion )
728         throws ArtifactResolutionException, InvalidVersionSpecificationException
729     {
730         ScopeArtifactFilter filter;
731         if ( Artifact.SCOPE_PROVIDED.equals( expectedScope ) )
732         {
733             filter = new ScopeArtifactFilter( Artifact.SCOPE_COMPILE );
734         }
735         else if ( Artifact.SCOPE_SYSTEM.equals( expectedScope ) )
736         {
737             filter = new ScopeArtifactFilter( Artifact.SCOPE_COMPILE );
738         }
739         else
740         {
741             filter = new ScopeArtifactFilter( expectedScope );
742         }
743 
744         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, b.artifact} ), filter );
745         Artifact artifact = getArtifact( "d", res.getArtifacts() );
746         assertNotNull( "MNG-1895 Dependency was not added to resolution", artifact );
747         assertEquals( "Check scope", expectedScope, artifact.getScope() );
748         assertEquals( "Check version", expectedVersion, artifact.getVersion() );
749 
750         ArtifactSpec d = createArtifactSpec( "d", "1.0" );
751         res = collect( createSet( new Object[]{a.artifact, b.artifact, d.artifact} ), filter );
752         artifact = getArtifact( "d", res.getArtifacts() );
753         assertNotNull( "MNG-1895 Dependency was not added to resolution", artifact );
754         assertEquals( "Check scope", d.artifact.getScope(), artifact.getScope() );
755         assertEquals( "Check version", "1.0", artifact.getVersion() );
756     }
757 
758     public void disabledtestOptionalNotTransitiveButVersionIsInfluential()
759         throws ArtifactResolutionException, InvalidVersionSpecificationException
760     {
761         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
762         ArtifactSpec b = createArtifactSpec( "b", "1.0" );
763         b.addDependency( "c", "3.0", true );
764         ArtifactSpec d = a.addDependency( "d", "1.0" );
765         ArtifactSpec e = d.addDependency( "e", "1.0" );
766         e.addDependency( "c", "2.0" );
767 
768         ArtifactSpec c = createArtifactSpec( "c", "3.0" );
769 
770         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, b.artifact} ) );
771         assertEquals( "Check artifact list",
772                       createSet( new Object[]{a.artifact, b.artifact, c.artifact, d.artifact, e.artifact} ),
773                       res.getArtifacts() );
774         Artifact artifact = getArtifact( "c", res.getArtifacts() );
775         assertEquals( "Check version", "3.0", artifact.getVersion() );
776     }
777 
778     public void testTestScopeNotTransitive()
779         throws ArtifactResolutionException, InvalidVersionSpecificationException
780     {
781         ArtifactSpec a = createArtifactSpec( "a", "1.0", Artifact.SCOPE_TEST );
782         ArtifactSpec b = createArtifactSpec( "b", "1.0" );
783         b.addDependency( "c", "3.0", Artifact.SCOPE_TEST );
784 
785         ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, b.artifact} ) );
786         assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact} ), res.getArtifacts() );
787     }
788 
789     public void testResolveOrder()
790         throws ArtifactResolutionException, InvalidVersionSpecificationException
791     {
792         ArtifactSpec m = createArtifactSpec( "m", "1.0" );
793         ArtifactSpec n = createArtifactSpec( "n", "1.0" );
794 
795         ArtifactResolutionResult res = collect( createSet( new Object[]{m.artifact, n.artifact} ) );
796         Iterator i = res.getArtifacts().iterator();
797         assertEquals( "m should be first", m.artifact, i.next() );
798         assertEquals( "n should be second", n.artifact, i.next() );
799 
800         res = collect( createSet( new Object[]{n.artifact, m.artifact} ) );
801         i = res.getArtifacts().iterator();
802         assertEquals( "n should be first", n.artifact, i.next() );
803         assertEquals( "m should be second", m.artifact, i.next() );
804     }
805 
806     public void testOverConstrainedVersionException()
807         throws ArtifactResolutionException, InvalidVersionSpecificationException
808     {
809         ArtifactSpec a = createArtifactSpec( "a", "1.0" );
810         a.addDependency( "b", "[1.0, 2.0)" );
811         a.addDependency( "c", "[3.3.0,4.0.0)" );
812 
813         ArtifactSpec b = createArtifactSpec( "b", "1.0.0" );
814         b.addDependency( "c", "3.3.0-v3346" );
815 
816         ArtifactSpec c = createArtifactSpec( "c", "3.2.1-v3235e" );
817 
818         try
819         {
820             ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact} ) );
821         }
822         catch ( OverConstrainedVersionException e )
823         {
824             assertTrue( "Versions unordered", e.getMessage().indexOf( "[3.2.1-v3235e, 3.3.0-v3346]" ) != -1);
825             assertTrue( "DependencyTrail not resolved", e.getMessage().indexOf( "Path to dependency:" ) != -1);
826         }
827     }
828 
829     private Artifact getArtifact( String id, Set artifacts )
830     {
831         for ( Iterator i = artifacts.iterator(); i.hasNext(); )
832         {
833             Artifact a = (Artifact) i.next();
834             if ( a.getArtifactId().equals( id ) && a.getGroupId().equals( GROUP_ID ) )
835             {
836                 return a;
837             }
838         }
839         return null;
840     }
841 
842     private ArtifactResolutionResult collect( Set artifacts )
843         throws ArtifactResolutionException
844     {
845         return collect( artifacts, null );
846     }
847 
848     private ArtifactResolutionResult collect( Set artifacts, ArtifactFilter filter )
849         throws ArtifactResolutionException
850     {
851         return artifactCollector.collect( artifacts, projectArtifact.artifact, null, null, source, filter,
852                                           Collections.EMPTY_LIST );
853     }
854 
855     private ArtifactResolutionResult collect( ArtifactSpec a )
856         throws ArtifactResolutionException
857     {
858         return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact, null, null,
859                                           source, null, Collections.EMPTY_LIST );
860     }
861 
862     private ArtifactResolutionResult collect( ArtifactSpec a, ArtifactFilter filter )
863         throws ArtifactResolutionException
864     {
865         return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact, null, null,
866                                           source, filter, Collections.EMPTY_LIST );
867     }
868 
869     private ArtifactResolutionResult collect( ArtifactSpec a, Artifact managedVersion )
870         throws ArtifactResolutionException
871     {
872         Map managedVersions = Collections.singletonMap( managedVersion.getDependencyConflictId(), managedVersion );
873         return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact,
874                                           managedVersions, null, null, source, null, Collections.EMPTY_LIST );
875     }
876 
877     private ArtifactSpec createArtifactSpec( String id, String version )
878         throws InvalidVersionSpecificationException
879     {
880         return createArtifactSpec( id, version, Artifact.SCOPE_COMPILE );
881     }
882 
883     private ArtifactSpec createArtifactSpec( String id, String version, boolean optional )
884         throws InvalidVersionSpecificationException
885     {
886         return createArtifactSpec( id, version, Artifact.SCOPE_COMPILE, null, optional );
887     }
888 
889     private ArtifactSpec createArtifactSpec( String id, String version, String scope )
890         throws InvalidVersionSpecificationException
891     {
892         return createArtifactSpec( id, version, scope, null, false );
893     }
894 
895     private ArtifactSpec createArtifactSpec( String id, String version, String scope, String inheritedScope,
896                                          boolean optional )
897         throws InvalidVersionSpecificationException
898     {
899         VersionRange versionRange = VersionRange.createFromVersionSpec( version );
900         Artifact artifact = artifactFactory.createDependencyArtifact( GROUP_ID, id, versionRange, "jar", null, scope,
901                                                                       inheritedScope, optional );
902         ArtifactSpec spec = null;
903         if ( artifact != null )
904         {
905             spec = new ArtifactSpec();
906             spec.artifact = artifact;
907             source.addArtifact( spec );
908         }
909         return spec;
910     }
911 
912     private static Set createSet( Object[] x )
913     {
914         return new LinkedHashSet( Arrays.asList( x ) );
915     }
916 
917     private class ArtifactSpec
918     {
919         private Artifact artifact;
920 
921         private Set dependencies = new HashSet();
922 
923         public ArtifactSpec addDependency( String id, String version )
924             throws InvalidVersionSpecificationException
925         {
926             return addDependency( id, version, Artifact.SCOPE_COMPILE );
927         }
928 
929         public ArtifactSpec addDependency( String id, String version, String scope )
930             throws InvalidVersionSpecificationException
931         {
932             return addDependency( id, version, scope, false );
933         }
934 
935         private ArtifactSpec addDependency( ArtifactSpec dep )
936             throws InvalidVersionSpecificationException
937         {
938             if ( dep != null )
939             {
940                 dependencies.add( dep.artifact );
941             }
942             return dep;
943         }
944 
945         private ArtifactSpec addDependency( String id, String version, String scope, boolean optional )
946             throws InvalidVersionSpecificationException
947         {
948             ArtifactSpec dep = createArtifactSpec( id, version, scope, artifact.getScope(), optional );
949             return addDependency( dep );
950         }
951 
952         public ArtifactSpec addDependency( String id, String version, boolean optional )
953             throws InvalidVersionSpecificationException
954         {
955             return addDependency( id, version, Artifact.SCOPE_COMPILE, optional );
956         }
957     }
958 
959     private class Source
960         implements ArtifactMetadataSource
961     {
962         private Map artifacts = new HashMap();
963 
964         private Map versions = new HashMap();
965 
966         public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository,
967                                          List remoteRepositories )
968             throws ArtifactMetadataRetrievalException
969         {
970             String key = getKey( artifact );
971 
972             ArtifactSpec a = (ArtifactSpec) artifacts.get( key );
973             try
974             {
975                 return new ResolutionGroup( artifact, createArtifacts( artifactFactory, a.dependencies,
976                                                                        artifact.getScope(),
977                                                                        artifact.getDependencyFilter() ),
978                                                       Collections.EMPTY_LIST );
979             }
980             catch ( InvalidVersionSpecificationException e )
981             {
982                 throw new ArtifactMetadataRetrievalException( "Invalid version creating artifacts", e, artifact );
983             }
984         }
985 
986         private String getKey( Artifact artifact )
987         {
988             return artifact.getDependencyConflictId() + ":" + artifact.getVersion();
989             //return artifact.getDependencyConflictId();
990         }
991 
992         private Set createArtifacts( ArtifactFactory artifactFactory, Set dependencies, String inheritedScope,
993                                      ArtifactFilter dependencyFilter )
994             throws InvalidVersionSpecificationException
995         {
996             Set projectArtifacts = new LinkedHashSet();
997 
998             for ( Iterator i = dependencies.iterator(); i.hasNext(); )
999             {
1000                 Artifact d = (Artifact) i.next();
1001 
1002                 VersionRange versionRange;
1003                 if ( d.getVersionRange() != null )
1004                 {
1005                     versionRange = d.getVersionRange();
1006                 }
1007                 else
1008                 {
1009                     versionRange = VersionRange.createFromVersionSpec( d.getVersion() );
1010                 }
1011                 Artifact artifact;
1012                 if ( d.getScope().equals( Artifact.SCOPE_TEST ) || d.getScope().equals( Artifact.SCOPE_PROVIDED ) )
1013                 {
1014                     /* don't call createDependencyArtifact as it'll ignore test and provided scopes */
1015                     artifact = artifactFactory.createArtifact( d.getGroupId(), d.getArtifactId(), d.getVersion(), d
1016                         .getScope(), d.getType() );
1017                 }
1018                 else
1019                 {
1020                     artifact = artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(),
1021                                                                          versionRange, d.getType(), d.getClassifier(),
1022                                                                          d.getScope(), inheritedScope, d.isOptional() );
1023                 }
1024 
1025                 if ( artifact != null && ( dependencyFilter == null || dependencyFilter.include( artifact ) ) )
1026                 {
1027                     artifact.setDependencyFilter( dependencyFilter );
1028 
1029                     projectArtifacts.add( artifact );
1030                 }
1031             }
1032 
1033             return projectArtifacts;
1034         }
1035 
1036         public List retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository,
1037                                                List remoteRepositories )
1038             throws ArtifactMetadataRetrievalException
1039         {
1040             List artifactVersions = (List) versions.get( artifact.getDependencyConflictId() );
1041             if ( artifactVersions == null )
1042             {
1043                 artifactVersions = Collections.EMPTY_LIST;
1044             }
1045             return artifactVersions;
1046         }
1047 
1048         public void addArtifact( ArtifactSpec spec )
1049         {
1050             artifacts.put( getKey( spec.artifact ), spec );
1051 
1052             String key = spec.artifact.getDependencyConflictId();
1053             List artifactVersions = (List) versions.get( key );
1054             if ( artifactVersions == null )
1055             {
1056                 artifactVersions = new ArrayList();
1057                 versions.put( key, artifactVersions );
1058             }
1059             if ( spec.artifact.getVersion() != null )
1060             {
1061                 artifactVersions.add( new DefaultArtifactVersion( spec.artifact.getVersion() ) );
1062             }
1063         }
1064 
1065         public Artifact retrieveRelocatedArtifact( Artifact artifact,
1066                                                    ArtifactRepository localRepository,
1067                                                    List remoteRepositories )
1068             throws ArtifactMetadataRetrievalException
1069         {
1070             return artifact;
1071         }
1072     }
1073 }