private Set<String> populateRealm(
      ClassRealm classRealm, List<ClassRealmConstituent> constituents) {
    Set<String> includedIds = new LinkedHashSet<String>();

    if (logger.isDebugEnabled()) {
      logger.debug("Populating class realm " + classRealm.getId());
    }

    for (ClassRealmConstituent constituent : constituents) {
      File file = constituent.getFile();

      String id = getId(constituent);
      includedIds.add(id);

      if (logger.isDebugEnabled()) {
        logger.debug("  Included: " + id);
      }

      try {
        classRealm.addURL(file.toURI().toURL());
      } catch (MalformedURLException e) {
        // Not going to happen
        logger.error(e.getMessage(), e);
      }
    }

    return includedIds;
  }
  /**
   * Retrieves dependency information from Spring XML configuration files in a Maven project.
   *
   * @param project the project to analyze
   * @param dependentClasses A set of classes that already had their dependencies analyzed. This
   *     method will <b>ADD</b> all Spring-induced dependencies to this set and also use it to
   *     determine whether a given class needs to have it's dependencies analyzed.
   * @throws Exception
   */
  public void addSpringDependencyClasses(MavenProject project, final Set<String> dependentClasses)
      throws Exception {
    final SpringFileBeanVisitor beanVisitor =
        new DefaultSpringXmlBeanVisitor(this.resolver, dependentClasses);

    for (File springXml : fileLocator.locateSpringXmls(project)) {
      final BufferedInputStream in = new BufferedInputStream(new FileInputStream(springXml));
      try {
        fileParser.parse(in, beanVisitor);
        if (log != null && log.isInfoEnabled()) {
          log.info("Scanned Spring XML " + springXml.getPath());
        }
      } catch (NoSpringXmlException ex) {
        if (log != null && log.isDebugEnabled()) {
          log.debug("Not a Spring XML file : " + springXml.getPath());
        }
        // ok
      } catch (Exception e) {
        if (log != null) {
          log.error("Failed to parse Spring XML " + springXml.getPath() + " ...", e);
        }
        throw e;
      } finally {
        in.close();
      }
    }
  }
  public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles(String packaging) {
    if (logger.isDebugEnabled()) {
      logger.debug(
          "Looking up lifecyle mappings for packaging "
              + packaging
              + " from "
              + Thread.currentThread().getContextClassLoader());
    }

    LifecycleMapping lifecycleMappingForPackaging = lifecycleMappings.get(packaging);

    if (lifecycleMappingForPackaging == null) {
      return null;
    }

    Map<Plugin, Plugin> plugins = new LinkedHashMap<>();

    for (Lifecycle lifecycle : getOrderedLifecycles()) {
      org.apache.maven.lifecycle.mapping.Lifecycle lifecycleConfiguration =
          lifecycleMappingForPackaging.getLifecycles().get(lifecycle.getId());

      Map<String, LifecyclePhase> phaseToGoalMapping = null;

      if (lifecycleConfiguration != null) {
        phaseToGoalMapping = lifecycleConfiguration.getPhases();
      } else if (lifecycle.getDefaultPhases() != null) {
        phaseToGoalMapping = lifecycle.getDefaultPhases();
      }

      if (phaseToGoalMapping != null) {
        for (Map.Entry<String, LifecyclePhase> goalsForLifecyclePhase :
            phaseToGoalMapping.entrySet()) {
          String phase = goalsForLifecyclePhase.getKey();
          LifecyclePhase goals = goalsForLifecyclePhase.getValue();
          if (goals != null) {
            parseLifecyclePhaseDefinitions(plugins, phase, goals);
          }
        }
      }
    }

    return plugins.keySet();
  }
  private ClassRealm newRealm(String id) {
    ClassWorld world = getClassWorld();

    synchronized (world) {
      String realmId = id;

      Random random = new Random();

      while (true) {
        try {
          ClassRealm classRealm = world.newRealm(realmId, null);

          if (logger.isDebugEnabled()) {
            logger.debug("Created new class realm " + realmId);
          }

          return classRealm;
        } catch (DuplicateRealmException e) {
          realmId = id + '-' + random.nextInt();
        }
      }
    }
  }
  public TargetPlatformConfiguration getTargetPlatformConfiguration(
      MavenSession session, MavenProject project) {
    TargetPlatformConfiguration result = new TargetPlatformConfiguration();

    // Use org.eclipse.tycho:target-platform-configuration/configuration/environment, if provided
    Plugin plugin = project.getPlugin("org.eclipse.tycho:target-platform-configuration");

    if (plugin != null) {
      Xpp3Dom configuration = (Xpp3Dom) plugin.getConfiguration();
      if (configuration != null) {
        if (logger.isDebugEnabled()) {
          logger.debug(
              "target-platform-configuration for "
                  + project.toString()
                  + ":\n"
                  + configuration.toString());
        }

        addTargetEnvironments(result, project, configuration);

        setTargetPlatformResolver(result, configuration);

        setTarget(result, session, project, configuration);

        setPomDependencies(result, configuration);

        setAllowConflictingDependencies(result, configuration);

        setDisableP2Mirrors(result, configuration);

        setExecutionEnvironment(result, configuration);

        readFilters(result, configuration);

        readExtraRequirements(result, configuration);

        setOptionalDependencies(result, configuration);

        setIncludePackedArtifacts(result, configuration);
      }
    }

    if (result.getEnvironments().isEmpty()) {
      TychoProject projectType = projectTypes.get(project.getPackaging());
      if (projectType != null) {
        TargetEnvironment env = projectType.getImplicitTargetEnvironment(project);
        if (env != null) {
          if (logger.isDebugEnabled()) {
            logger.debug(
                "Implicit target environment for " + project.toString() + ": " + env.toString());
          }

          result.addEnvironment(env);
        }
      }
    }

    if (result.getEnvironments().isEmpty()) {
      // applying defaults
      logger.warn(
          "No explicit target runtime environment configuration. Build is platform dependent.");

      // Otherwise, use project or execution properties, if provided
      Properties properties =
          (Properties) project.getContextValue(TychoConstants.CTX_MERGED_PROPERTIES);

      // Otherwise, use current system os/ws/nl/arch
      String os = PlatformPropertiesUtils.getOS(properties);
      String ws = PlatformPropertiesUtils.getWS(properties);
      String arch = PlatformPropertiesUtils.getArch(properties);

      result.addEnvironment(new TargetEnvironment(os, ws, arch));

      result.setImplicitTargetEnvironment(true);
    } else {
      result.setImplicitTargetEnvironment(false);
    }

    return result;
  }
  /**
   * Resolve project dependencies. Manual resolution is needed in order to avoid resoltion of
   * multiproject artifacts (if projects will be linked each other an installed jar is not needed)
   * and to avoid a failure when a jar is missing.
   *
   * @throws MojoExecutionException if dependencies can't be resolved
   * @return resoved IDE dependencies, with attached jars for non-reactor dependencies
   */
  protected IdeDependency[] doDependencyResolution() throws MojoExecutionException {
    MavenProject project = getProject();
    ArtifactRepository localRepo = getLocalRepository();

    List dependencies = getProject().getDependencies();

    // Collect the list of resolved IdeDependencies.
    List dependencyList = new ArrayList();

    if (dependencies != null) {
      Map managedVersions =
          createManagedVersionMap(
              getArtifactFactory(), project.getId(), project.getDependencyManagement());

      ArtifactResolutionResult artifactResolutionResult = null;

      try {

        List listeners = new ArrayList();

        if (logger.isDebugEnabled()) {
          listeners.add(new DebugResolutionListener(logger));
        }

        listeners.add(new WarningResolutionListener(logger));

        artifactResolutionResult =
            artifactCollector.collect(
                getProjectArtifacts(),
                project.getArtifact(),
                managedVersions,
                localRepo,
                project.getRemoteArtifactRepositories(),
                getArtifactMetadataSource(),
                null,
                listeners);
      } catch (ArtifactResolutionException e) {
        getLog().debug(e.getMessage(), e);
        getLog()
            .error(
                Messages.getString(
                    "artifactresolution",
                    new Object[] { // $NON-NLS-1$
                      e.getGroupId(), e.getArtifactId(), e.getVersion(), e.getMessage()
                    }));

        // if we are here artifactResolutionResult is null, create a project without dependencies
        // but don't fail
        // (this could be a reactor projects, we don't want to fail everything)
        return new IdeDependency[0];
      }

      // keep track of added reactor projects in order to avoid duplicates
      Set emittedReactorProjectId = new HashSet();

      for (Iterator i = artifactResolutionResult.getArtifactResolutionNodes().iterator();
          i.hasNext(); ) {
        ResolutionNode node = (ResolutionNode) i.next();
        Artifact art = node.getArtifact();
        boolean isReactorProject = getUseProjectReferences() && isAvailableAsAReactorProject(art);

        // don't resolve jars for reactor projects
        if (!isReactorProject) {
          try {
            artifactResolver.resolve(art, node.getRemoteRepositories(), localRepository);
          } catch (ArtifactNotFoundException e) {
            getLog().debug(e.getMessage(), e);
            getLog()
                .warn(
                    Messages.getString(
                        "artifactdownload",
                        new Object[] { // $NON-NLS-1$
                          e.getGroupId(), e.getArtifactId(), e.getVersion(), e.getMessage()
                        }));
          } catch (ArtifactResolutionException e) {
            getLog().debug(e.getMessage(), e);
            getLog()
                .warn(
                    Messages.getString(
                        "artifactresolution",
                        new Object[] { // $NON-NLS-1$
                          e.getGroupId(), e.getArtifactId(), e.getVersion(), e.getMessage()
                        }));
          }
        }

        if (!isReactorProject
            || emittedReactorProjectId.add(art.getGroupId() + '-' + art.getArtifactId())) {

          IdeDependency dep =
              new IdeDependency(
                  art.getGroupId(),
                  art.getArtifactId(),
                  art.getVersion(),
                  isReactorProject,
                  Artifact.SCOPE_TEST.equals(art.getScope()),
                  Artifact.SCOPE_SYSTEM.equals(art.getScope()),
                  Artifact.SCOPE_PROVIDED.equals(art.getScope()),
                  art.getArtifactHandler().isAddedToClasspath(),
                  art.getFile(),
                  art.getType());

          dependencyList.add(dep);
        }
      }

      // @todo a final report with the list of missingArtifacts?

    }

    IdeDependency[] deps =
        (IdeDependency[]) dependencyList.toArray(new IdeDependency[dependencyList.size()]);

    return deps;
  }
  public ArtifactResolutionResult resolve(ArtifactResolutionRequest request) {
    Artifact rootArtifact = request.getArtifact();
    Set<Artifact> artifacts = request.getArtifactDependencies();
    Map<String, Artifact> managedVersions = request.getManagedVersionMap();
    List<ResolutionListener> listeners = request.getListeners();
    ArtifactFilter collectionFilter = request.getCollectionFilter();
    ArtifactFilter resolutionFilter = request.getResolutionFilter();
    RepositorySystemSession session = getSession(request.getLocalRepository());

    // TODO: hack because metadata isn't generated in m2e correctly and i want to run the maven i
    // have in the workspace
    if (source == null) {
      try {
        source = container.lookup(ArtifactMetadataSource.class);
      } catch (ComponentLookupException e) {
        // won't happen
      }
    }

    if (listeners == null) {
      listeners = new ArrayList<ResolutionListener>();

      if (logger.isDebugEnabled()) {
        listeners.add(new DebugResolutionListener(logger));
      }

      listeners.add(new WarningResolutionListener(logger));
    }

    ArtifactResolutionResult result = new ArtifactResolutionResult();

    // The root artifact may, or may not be resolved so we need to check before we attempt to
    // resolve.
    // This is often an artifact like a POM that is taken from disk and we already have hold of the
    // file reference. But this may be a Maven Plugin that we need to resolve from a remote
    // repository
    // as well as its dependencies.

    if (request.isResolveRoot() /* && rootArtifact.getFile() == null */) {
      try {
        resolve(rootArtifact, request.getRemoteRepositories(), session);
      } catch (ArtifactResolutionException e) {
        result.addErrorArtifactException(e);
        return result;
      } catch (ArtifactNotFoundException e) {
        result.addMissingArtifact(request.getArtifact());
        return result;
      }
    }

    ArtifactResolutionRequest collectionRequest = request;

    if (request.isResolveTransitively()) {
      MetadataResolutionRequest metadataRequest = new DefaultMetadataResolutionRequest(request);

      metadataRequest.setArtifact(rootArtifact);
      metadataRequest.setResolveManagedVersions(managedVersions == null);

      try {
        ResolutionGroup resolutionGroup = source.retrieve(metadataRequest);

        if (managedVersions == null) {
          managedVersions = resolutionGroup.getManagedVersions();
        }

        Set<Artifact> directArtifacts = resolutionGroup.getArtifacts();

        if (artifacts == null || artifacts.isEmpty()) {
          artifacts = directArtifacts;
        } else {
          List<Artifact> allArtifacts = new ArrayList<Artifact>();
          allArtifacts.addAll(artifacts);
          allArtifacts.addAll(directArtifacts);

          Map<String, Artifact> mergedArtifacts = new LinkedHashMap<String, Artifact>();
          for (Artifact artifact : allArtifacts) {
            String conflictId = artifact.getDependencyConflictId();
            if (!mergedArtifacts.containsKey(conflictId)) {
              mergedArtifacts.put(conflictId, artifact);
            }
          }

          artifacts = new LinkedHashSet<Artifact>(mergedArtifacts.values());
        }

        collectionRequest = new ArtifactResolutionRequest(request);
        collectionRequest.setServers(request.getServers());
        collectionRequest.setMirrors(request.getMirrors());
        collectionRequest.setProxies(request.getProxies());
        collectionRequest.setRemoteRepositories(resolutionGroup.getResolutionRepositories());
      } catch (ArtifactMetadataRetrievalException e) {
        ArtifactResolutionException are =
            new ArtifactResolutionException(
                "Unable to get dependency information for "
                    + rootArtifact.getId()
                    + ": "
                    + e.getMessage(),
                rootArtifact,
                metadataRequest.getRemoteRepositories(),
                e);
        result.addMetadataResolutionException(are);
        return result;
      }
    }

    if (artifacts == null || artifacts.isEmpty()) {
      if (request.isResolveRoot()) {
        result.addArtifact(rootArtifact);
      }
      return result;
    }

    // After the collection we will have the artifact object in the result but they will not be
    // resolved yet.
    result =
        artifactCollector.collect(
            artifacts,
            rootArtifact,
            managedVersions,
            collectionRequest,
            source,
            collectionFilter,
            listeners,
            null);

    // We have metadata retrieval problems, or there are cycles that have been detected
    // so we give this back to the calling code and let them deal with this information
    // appropriately.

    if (result.hasMetadataResolutionExceptions()
        || result.hasVersionRangeViolations()
        || result.hasCircularDependencyExceptions()) {
      return result;
    }

    if (result.getArtifactResolutionNodes() != null) {
      ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

      CountDownLatch latch = new CountDownLatch(result.getArtifactResolutionNodes().size());

      for (ResolutionNode node : result.getArtifactResolutionNodes()) {
        Artifact artifact = node.getArtifact();

        if (resolutionFilter == null || resolutionFilter.include(artifact)) {
          executor.execute(
              new ResolveTask(
                  classLoader, latch, artifact, session, node.getRemoteRepositories(), result));
        } else {
          latch.countDown();
        }
      }
      try {
        latch.await();
      } catch (InterruptedException e) {
        result.addErrorArtifactException(
            new ArtifactResolutionException("Resolution interrupted", rootArtifact, e));
      }
    }

    // We want to send the root artifact back in the result but we need to do this after the other
    // dependencies
    // have been resolved.
    if (request.isResolveRoot()) {
      // Add the root artifact (as the first artifact to retain logical order of class path!)
      Set<Artifact> allArtifacts = new LinkedHashSet<Artifact>();
      allArtifacts.add(rootArtifact);
      allArtifacts.addAll(result.getArtifacts());
      result.setArtifacts(allArtifacts);
    }

    return result;
  }
  /**
   * Creates a new class realm with the specified parent and imports.
   *
   * @param baseRealmId The base id to use for the new realm, must not be {@code null}.
   * @param type The type of the class realm, must not be {@code null}.
   * @param parent The parent realm for the new realm, may be {@code null} to use the Maven core
   *     realm.
   * @param imports The packages/types to import from the parent realm, may be {@code null}.
   * @param artifacts The artifacts to add to the realm, may be {@code null}. Unresolved artifacts
   *     (i.e. with a missing file) will automatically be excluded from the realm.
   * @return The created class realm, never {@code null}.
   */
  private ClassRealm createRealm(
      String baseRealmId,
      RealmType type,
      ClassLoader parent,
      List<String> imports,
      boolean importXpp3Dom,
      List<Artifact> artifacts) {
    Set<String> artifactIds = new LinkedHashSet<String>();

    List<ClassRealmConstituent> constituents = new ArrayList<ClassRealmConstituent>();

    if (artifacts != null) {
      for (Artifact artifact : artifacts) {
        artifactIds.add(getId(artifact));
        if (artifact.getFile() != null) {
          constituents.add(new ArtifactClassRealmConstituent(artifact));
        }
      }
    }

    if (imports != null) {
      imports = new ArrayList<String>(imports);
    } else {
      imports = new ArrayList<String>();
    }

    ClassRealm classRealm = newRealm(baseRealmId);

    if (parent != null) {
      classRealm.setParentClassLoader(parent);
    } else {
      classRealm.setParentRealm(getMavenRealm());
    }

    List<ClassRealmManagerDelegate> delegates = getDelegates();
    if (!delegates.isEmpty()) {
      ClassRealmRequest request = new DefaultClassRealmRequest(type, parent, imports, constituents);

      for (ClassRealmManagerDelegate delegate : delegates) {
        delegate.setupRealm(classRealm, request);
      }
    }

    if (importXpp3Dom) {
      importXpp3Dom(classRealm);
    }

    if (!imports.isEmpty()) {
      ClassLoader importedRealm = classRealm.getParentClassLoader();

      if (logger.isDebugEnabled()) {
        logger.debug("Importing packages into class realm " + classRealm.getId());
      }

      for (String imp : imports) {
        if (logger.isDebugEnabled()) {
          logger.debug("  Imported: " + imp);
        }

        classRealm.importFrom(importedRealm, imp);
      }
    }

    Set<String> includedIds = populateRealm(classRealm, constituents);

    if (logger.isDebugEnabled()) {
      artifactIds.removeAll(includedIds);

      for (String id : artifactIds) {
        logger.debug("  Excluded: " + id);
      }
    }

    return classRealm;
  }