/**
   * @param project MavenProject for which to return the dependencies.
   * @param session MavenSession in which to look for reactor dependencies.
   * @return all the dependencies for a project.
   * @throws DependencyGraphBuilderException if the dependency graph can't be built.
   */
  public Set<Artifact> getProjectDependenciesFor(MavenProject project, MavenSession session)
      throws DependencyGraphBuilderException {
    // No need to filter our search. We want to resolve all artifacts.
    final DependencyNode node =
        dependencyGraphBuilder.buildDependencyGraph(project, null, session.getProjects());

    final DependencyCollector collector = new DependencyCollector(log, project.getArtifact());
    collector.visit(node, false);
    return collector.getDependencies();
  }
  private Set<Artifact> processTransitiveDependencies(
      Dependency dependency, boolean sharedLibraries) throws MojoExecutionException {
    log.debug("Processing transitive dependencies for : " + dependency);

    try {
      final Set<Artifact> artifacts = new LinkedHashSet<Artifact>();

      final List<String> exclusionPatterns = new ArrayList<String>();
      if (dependency.getExclusions() != null && !dependency.getExclusions().isEmpty()) {
        for (final Exclusion exclusion : dependency.getExclusions()) {
          exclusionPatterns.add(exclusion.getGroupId() + ":" + exclusion.getArtifactId());
        }
      }
      final ArtifactFilter optionalFilter =
          new ArtifactFilter() {
            @Override
            public boolean include(Artifact artifact) {
              return !artifact.isOptional();
            }
          };

      final AndArtifactFilter filter = new AndArtifactFilter();
      filter.add(new ExcludesArtifactFilter(exclusionPatterns));
      filter.add(
          new OrArtifactFilter(
              Arrays.<ArtifactFilter>asList(
                  new ScopeArtifactFilter("compile"),
                  new ScopeArtifactFilter("runtime"),
                  new ScopeArtifactFilter("test"))));
      filter.add(optionalFilter);

      final DependencyNode node = dependencyGraphBuilder.buildDependencyGraph(project, filter);
      final CollectingDependencyNodeVisitor collectingVisitor =
          new CollectingDependencyNodeVisitor();
      node.accept(collectingVisitor);

      final List<DependencyNode> dependencies = collectingVisitor.getNodes();
      for (final DependencyNode dep : dependencies) {
        final boolean isNativeLibrary =
            isNativeLibrary(sharedLibraries, dep.getArtifact().getType());
        log.debug("Processing library : " + dep.getArtifact() + " isNative=" + isNativeLibrary);
        if (isNativeLibrary) {
          artifacts.add(dep.getArtifact());
        }
      }

      return artifacts;
    } catch (Exception e) {
      throw new MojoExecutionException("Error while processing transitive dependencies", e);
    }
  }
  /** @param featuresXml */
  private void generate(FeaturesXml featuresXml) throws Exception {
    // Add the repositories
    if (this.repositories != null) {
      for (String repo : repositories) {
        featuresXml.addRepository(repo);
      }
    }

    // Collect all dependencies (bundle candidates)
    ScopeArtifactFilter filter = new ScopeArtifactFilter(DefaultArtifact.SCOPE_RUNTIME);
    DependencyNode dependencyGraph = dependencyGraphBuilder.buildDependencyGraph(project, filter);
    CollectingDependencyNodeVisitor collectingVizzy = new CollectingDependencyNodeVisitor();
    dependencyGraph.accept(collectingVizzy);
    List<DependencyNode> nodes = collectingVizzy.getNodes();

    // Iterate all features
    for (Feature feature : features) {
      getLog().info("Generating feature '" + feature.getName() + "'"); // $NON-NLS-1$ //$NON-NLS-2$
      // Create the feature
      featuresXml.addFeature(feature.getName(), feature.getVersion(), feature.getComment());
      // Add any feature dependencies
      List<Feature> onFeatures = feature.getDependsOnFeatures();
      if (onFeatures != null && !onFeatures.isEmpty()) {
        for (Feature onFeature : onFeatures) {
          getLog()
              .info(
                  "   Depends on feature: "
                      + onFeature.getName()
                      + "/"
                      + onFeature.getVersion()); // $NON-NLS-1$ //$NON-NLS-2$
          featuresXml.addFeatureDependency(
              feature.getName(), feature.getVersion(), onFeature.getName(), onFeature.getVersion());
        }
      }
      // Add any included or non-excluded bundles (from artifact
      // dependency graph)
      PatternIncludesArtifactFilter includesFilter =
          new PatternIncludesArtifactFilter(feature.getIncludes());
      PatternExcludesArtifactFilter excludesFilter =
          new PatternExcludesArtifactFilter(feature.getExcludes());
      String startLevel = feature.getStartLevel();
      for (DependencyNode dependencyNode : nodes) {
        if (isSelf(dependencyNode)) continue;
        Artifact artifact = dependencyNode.getArtifact();
        // If no includes, assume everything
        boolean includeBundle = feature.getIncludes() == null || feature.getIncludes().isEmpty();
        if (includeBundle) {
          getLog()
              .debug(
                  "   Artifact "
                      + artifact
                      + " matches default [all] filter (including)."); //$NON-NLS-1$ //$NON-NLS-2$
        }
        if (includesFilter.include(artifact)) {
          getLog()
              .debug(
                  "   Artifact "
                      + artifact
                      + " matched include filter (including)."); //$NON-NLS-1$ //$NON-NLS-2$
          includeBundle = true;
        }
        // Excludes must be explicit.
        if (!excludesFilter.include(artifact)) {
          getLog()
              .debug(
                  "   Artifact "
                      + artifact
                      + " matched exclude filter (excluding)."); //$NON-NLS-1$ //$NON-NLS-2$
          includeBundle = false;
        }

        if (includeBundle) {
          featuresXml.addBundle(
              feature.getName(),
              feature.getVersion(),
              formatArtifactAsBundle(artifact),
              startLevel);
        }
      }

      // Add additional explicit bundles specified in the config
      List<String> bundles = feature.getBundles();
      if (bundles != null && !bundles.isEmpty()) {
        for (String bundle : bundles) {
          getLog().debug("   Adding explicit bundle: " + bundle); // $NON-NLS-1$
          featuresXml.addBundle(feature.getName(), feature.getVersion(), bundle, startLevel);
        }
      }

      // Add config files if any are specified in the pom
      List<ConfigFile> configFiles = feature.getConfigFiles();
      if (configFiles != null && !configFiles.isEmpty()) {
        for (ConfigFile configFile : configFiles) {
          getLog().debug("   Adding config file: " + configFile.getValue()); // $NON-NLS-1$
          featuresXml.addConfigFile(
              feature.getName(),
              feature.getVersion(),
              configFile.getFinalName(),
              configFile.getValue());
        }
      }
    }
  }