public void testDependencyManagementOverridesTransitiveDependencyVersion() throws Exception {
    File localRepo = getLocalRepositoryPath();

    File pom0 = new File(localRepo, "p0/pom.xml");
    File pom0Basedir = pom0.getParentFile();
    File pom1 = new File(pom0Basedir, "p1/pom.xml");

    // load the child project, which inherits from p0...
    MavenProject project0 = getProjectWithDependencies(pom0);
    MavenProject project1 = getProjectWithDependencies(pom1);

    assertEquals(pom0Basedir, project1.getParent().getBasedir());
    System.out.println("Project " + project1.getId() + " " + project1);
    Map map = project1.getArtifactMap();
    assertNotNull("No artifacts", map);
    assertTrue("No Artifacts", map.size() > 0);
    assertTrue("Set size should be 3, is " + map.size(), map.size() == 3);

    Artifact a = (Artifact) map.get("maven-test:t10-a");
    Artifact b = (Artifact) map.get("maven-test:t10-b");
    Artifact c = (Artifact) map.get("maven-test:t10-c");

    assertNotNull(a);
    assertNotNull(b);
    assertNotNull(c);

    // inherited from depMgmt
    System.out.println(a.getScope());
    assertTrue("Incorrect scope for " + a.getDependencyConflictId(), a.getScope().equals("test"));

    // transitive dep, overridden b depMgmt
    assertTrue(
        "Incorrect scope for " + b.getDependencyConflictId(), b.getScope().equals("runtime"));

    // direct dep, overrides depMgmt
    assertTrue(
        "Incorrect scope for " + c.getDependencyConflictId(), c.getScope().equals("runtime"));
  }
  public void configureClasspath(
      IProject project,
      MavenProject mavenProject,
      IClasspathDescriptor classpath,
      IProgressMonitor monitor)
      throws CoreException {

    // Improve skinny war support by generating the manifest classpath
    // similar to mvn eclipse:eclipse
    // http://maven.apache.org/plugins/maven-war-plugin/examples/skinny-wars.html
    WarPluginConfiguration config = new WarPluginConfiguration(mavenProject, project);
    WarPackagingOptions opts = new WarPackagingOptions(config);

    StringBuilder manifestCp = new StringBuilder();

    /*
     * Need to take care of three separate cases
     *
     * 1. remove any project dependencies (they are represented as J2EE module dependencies)
     * 2. add non-dependency attribute for entries originated by artifacts with
     *    runtime, system, test scopes or optional dependencies (not sure about the last one)
     * 3. make sure all dependency JAR files have unique file names, i.e. artifactId/version collisions
     */

    Set<String> dups = new LinkedHashSet<String>();
    Set<String> names = new HashSet<String>();

    // first pass removes projects, adds non-dependency attribute and collects colliding filenames
    Iterator<IClasspathEntryDescriptor> iter = classpath.getEntryDescriptors().iterator();
    while (iter.hasNext()) {
      IClasspathEntryDescriptor descriptor = iter.next();
      IClasspathEntry entry = descriptor.getClasspathEntry();
      String scope = descriptor.getScope();
      String key =
          ArtifactUtils.versionlessKey(descriptor.getGroupId(), descriptor.getArtifactId());
      Artifact artifact = mavenProject.getArtifactMap().get(key);
      String extension = artifact.getArtifactHandler().getExtension();

      if (IClasspathEntry.CPE_PROJECT == entry.getEntryKind()
          && Artifact.SCOPE_COMPILE.equals(scope)) {
        // get deployed name for project dependencies
        // TODO can this be done somehow more elegantly?
        IProject p =
            (IProject) ResourcesPlugin.getWorkspace().getRoot().findMember(entry.getPath());

        IVirtualComponent component = ComponentCore.createComponent(p);

        boolean usedInEar = opts.isReferenceFromEar(component, extension);
        if (opts.isSkinnyWar() && usedInEar) {
          if (manifestCp.length() > 0) {
            manifestCp.append(" ");
          }
          // MNGECLIPSE-2393 prepend ManifestClasspath prefix
          if (config.getManifestClasspathPrefix() != null
              && !JEEPackaging.isJEEPackaging(artifact.getType())) {
            manifestCp.append(config.getManifestClasspathPrefix());
          }

          manifestCp.append(component.getDeployedName()).append(".").append(extension);
        }

        if (!descriptor.isOptionalDependency() || usedInEar) {
          // remove mandatory project dependency from classpath
          iter.remove();
          continue;
        } // else : optional dependency not used in ear -> need to trick ClasspathAttribute with
          // NONDEPENDENCY_ATTRIBUTE
      }

      if (opts.isSkinnyWar() && opts.isReferenceFromEar(descriptor)) {

        if (manifestCp.length() > 0) {
          manifestCp.append(" ");
        }
        if (config.getManifestClasspathPrefix() != null
            && !JEEPackaging.isJEEPackaging(artifact.getType())) {
          manifestCp.append(config.getManifestClasspathPrefix());
        }
        manifestCp.append(entry.getPath().lastSegment());

        // ear references aren't kept in the Maven Dependencies
        iter.remove();
        continue;
      }

      // add non-dependency attribute
      // Check the scope & set WTP non-dependency as appropriate
      // Optional artifact shouldn't be deployed
      if (Artifact.SCOPE_PROVIDED.equals(scope)
          || Artifact.SCOPE_TEST.equals(scope)
          || Artifact.SCOPE_SYSTEM.equals(scope)
          || descriptor.isOptionalDependency()) {
        descriptor.addClasspathAttribute(NONDEPENDENCY_ATTRIBUTE);
      }

      // collect duplicate file names
      if (!names.add(entry.getPath().lastSegment())) {
        dups.add(entry.getPath().lastSegment());
      }
    }

    String targetDir = mavenProject.getBuild().getDirectory();

    // second pass disambiguates colliding entry file names
    iter = classpath.getEntryDescriptors().iterator();
    while (iter.hasNext()) {
      IClasspathEntryDescriptor descriptor = iter.next();
      IClasspathEntry entry = descriptor.getClasspathEntry();

      if (dups.contains(entry.getPath().lastSegment())) {
        File src = new File(entry.getPath().toOSString());
        String groupId = descriptor.getGroupId();
        File dst = new File(targetDir, groupId + "-" + entry.getPath().lastSegment());
        try {
          if (src.canRead()) {
            if (isDifferent(src, dst)) { // uses lastModified
              FileUtils.copyFile(src, dst);
              dst.setLastModified(src.lastModified());
            }
            descriptor.setClasspathEntry(
                JavaCore.newLibraryEntry(
                    Path.fromOSString(dst.getCanonicalPath()), //
                    entry.getSourceAttachmentPath(), //
                    entry.getSourceAttachmentRootPath(), //
                    entry.getAccessRules(), //
                    entry.getExtraAttributes(), //
                    entry.isExported()));
          }
        } catch (IOException ex) {
          MavenLogger.log("File copy failed", ex);
        }
      }
    }

    if (opts.isSkinnyWar()) {

      // writing the manifest only works when the project has been properly created
      // placing this check on the top of the method broke 2 other tests
      // thats why its placed here now.
      if (ComponentCore.createComponent(project) == null) {
        return;
      }

      // write manifest, using internal API - seems ok for 3.4/3.5, though
      ArchiveManifest mf = J2EEProjectUtilities.readManifest(project);
      if (mf == null) {
        mf = new ArchiveManifestImpl();
      }
      mf.addVersionIfNecessary();
      mf.setClassPath(manifestCp.toString());

      try {
        J2EEProjectUtilities.writeManifest(project, mf);
      } catch (Exception ex) {
        MavenLogger.log("Could not write web module manifest file", ex);
      }
    }
  }
  public void setModuleDependencies(
      IProject project, MavenProject mavenProject, IProgressMonitor monitor) throws CoreException {
    IVirtualComponent component = ComponentCore.createComponent(project);
    // if the attempt to create dependencies happens before the project is actually created, abort.
    // this will be created again when the project exists.
    if (component == null) {
      return;
    }

    WarPluginConfiguration config = new WarPluginConfiguration(mavenProject, project);
    WarPackagingOptions opts = new WarPackagingOptions(config);

    List<AbstractDependencyConfigurator> depConfigurators =
        ExtensionReader.readDependencyConfiguratorExtensions(
            projectManager,
            MavenPlugin.getDefault().getMavenRuntimeManager(),
            mavenMarkerManager,
            MavenPlugin.getDefault().getConsole());

    Set<IVirtualReference> references = new LinkedHashSet<IVirtualReference>();
    List<IMavenProjectFacade> exportedDependencies =
        getWorkspaceDependencies(project, mavenProject);
    for (IMavenProjectFacade dependency : exportedDependencies) {
      String depPackaging = dependency.getPackaging();
      if ("pom".equals(depPackaging))
        continue; // MNGECLIPSE-744 pom dependencies shouldn't be deployed

      preConfigureDependencyProject(dependency, monitor);
      MavenProject depMavenProject = dependency.getMavenProject(monitor);

      IVirtualComponent depComponent = ComponentCore.createComponent(dependency.getProject());

      String artifactKey = ArtifactUtils.versionlessKey(depMavenProject.getArtifact());
      Artifact artifact = mavenProject.getArtifactMap().get(artifactKey);
      // in a skinny war the dependency modules are referenced by manifest classpath
      // see also <code>configureClasspath</code> the dependeny project is handled in the skinny
      // case
      if (opts.isSkinnyWar()
          && opts.isReferenceFromEar(depComponent, artifact.getArtifactHandler().getExtension())) {
        continue;
      }

      // an artifact in mavenProject.getArtifacts() doesn't have the "optional" value as
      // depMavenProject.getArtifact();
      if (!artifact.isOptional()) {
        IVirtualReference reference = ComponentCore.createReference(component, depComponent);
        reference.setRuntimePath(new Path("/WEB-INF/lib"));
        references.add(reference);
      }
    }

    IVirtualReference[] newRefs = references.toArray(new IVirtualReference[references.size()]);
    if (hasChanged(component.getReferences(), newRefs)) {
      // Only write in the .component file if necessary
      component.setReferences(newRefs);
    }

    // TODO why a 2nd loop???
    for (IMavenProjectFacade dependency : exportedDependencies) {
      MavenProject depMavenProject = dependency.getMavenProject(monitor);
      Iterator<AbstractDependencyConfigurator> configurators = depConfigurators.iterator();
      while (configurators.hasNext()) {
        try {
          configurators
              .next()
              .configureDependency(
                  mavenProject, project, depMavenProject, dependency.getProject(), monitor);
        } catch (MarkedException ex) {
          // XXX handle this
        }
      }
    }
  }