private Set<App> whatRequires(String dependency, Set<String> visited) {
   final String mavenSettingsFile = settings.get("apps.settings", DEFAULT_SETTINGS);
   final boolean useMavenCentral = settings.getAsBoolean("apps.usemavencentral", Boolean.TRUE);
   final String[] defaultExcludes = settings.getAsArray("apps.excludes", DEFAULT_EXCLUDE);
   Set<App> foundDeps = Sets.newHashSet();
   for (App app : artifactApps.values()) {
     MavenDependencyExclusion[] exclusions = new MavenDependencyExclusion[defaultExcludes.length];
     for (int i = 0; i < defaultExcludes.length; i++) {
       exclusions[i] = MavenDependencies.createExclusion(defaultExcludes[i]);
     }
     MavenDependency dep =
         MavenDependencies.createDependency(
             app.getCanonicalForm(), ScopeType.RUNTIME, false, exclusions);
     MavenResolvedArtifact[] artifacts =
         Maven.configureResolver()
             .fromFile(mavenSettingsFile)
             .addDependencies(dep)
             .resolve()
             .withMavenCentralRepo(useMavenCentral)
             .withTransitivity()
             .asResolvedArtifact();
     if (artifacts != null && artifacts.length > 0) {
       visited.add(artifacts[0].getCoordinate().toCanonicalForm());
       for (MavenResolvedArtifact artifact : artifacts) {
         String artifactName = artifact.getCoordinate().toCanonicalForm();
         if (artifactName.startsWith(dependency)) {
           foundDeps.add(app);
         } else if (!visited.contains(artifactName)) {
           visited.add(artifactName);
           foundDeps.addAll(whatRequires(artifactName, visited));
         }
       }
     }
   }
   return foundDeps;
 }
 private Set<DependencyInfo> dependencyTree(
     String dependency, Set<DependencyInfo> visited, int level) {
   final String mavenSettingsFile = settings.get("apps.settings", DEFAULT_SETTINGS);
   final boolean useMavenCentral = settings.getAsBoolean("apps.usemavencentral", Boolean.TRUE);
   final String[] defaultExcludes = settings.getAsArray("apps.excludes", DEFAULT_EXCLUDE);
   MavenDependencyExclusion[] exclusions = new MavenDependencyExclusion[defaultExcludes.length];
   for (int i = 0; i < defaultExcludes.length; i++) {
     exclusions[i] = MavenDependencies.createExclusion(defaultExcludes[i]);
   }
   MavenDependency dep =
       MavenDependencies.createDependency(dependency, ScopeType.RUNTIME, false, exclusions);
   MavenResolvedArtifact[] artifacts =
       Maven.configureResolver()
           .fromFile(mavenSettingsFile)
           .addDependencies(dep)
           .resolve()
           .withMavenCentralRepo(useMavenCentral)
           .withTransitivity()
           .asResolvedArtifact();
   Set<DependencyInfo> foundDeps = Sets.newLinkedHashSet();
   if (artifacts != null && artifacts.length > 0) {
     DependencyInfo info = new DependencyInfo(artifacts[0], level);
     visited.add(info);
     foundDeps.add(info);
     for (MavenResolvedArtifact artifact : artifacts) {
       String artifactName = artifact.getCoordinate().toCanonicalForm();
       info = new DependencyInfo(artifact, level + 1);
       if (!visited.contains(info)) {
         visited.add(info);
         foundDeps.add(info);
         foundDeps.addAll(dependencyTree(artifactName, visited, level + 1));
       }
     }
   }
   return foundDeps;
 }
 /**
  * Helper method for loading artifacts and building a map of the artifact-based apps.
  *
  * @param artifacts the artifacts that will be checked for ES plugins
  * @return a map of artifacts
  */
 private Map<String, ArtifactApp> loadArtifacts(MavenResolvedArtifact[] artifacts) {
   Map<String, ArtifactApp> map = newHashMap();
   // no artifacts?
   if (artifacts == null) {
     logger.debug("no artifacts to load");
     return map;
   }
   // Now we want to know the relationship between class path and JAR.
   // build an URL map to assign found plugin on classpath to artifact
   Map<URI, MavenResolvedArtifact> jars = newHashMap();
   for (MavenResolvedArtifact artifact : artifacts) {
     if (artifact.getCoordinate().getType().equals(PackagingType.JAR)) {
       try {
         URI uri = artifact.asFile().toURI();
         classLoader.addUri(uri);
         jars.put(uri, artifact);
       } catch (Exception e) {
         logger.warn("failed to add [{}]", artifact.getCoordinate(), e);
       }
     } else {
       logger.warn("not a jar artifact: [{}]", artifact.getCoordinate());
     }
   }
   // now, that everything is on the class path, build the artifact app map.
   Enumeration<URL> propUrls = null;
   try {
     propUrls = classLoader.getResources(DEFAULT_RESOURCE);
   } catch (IOException e1) {
     logger.warn("failed to find resources on classpath", e1);
     return map;
   }
   while (propUrls.hasMoreElements()) {
     URL propUrl = propUrls.nextElement();
     Properties appProps = new Properties();
     InputStream is = null;
     try {
       is = propUrl.openStream();
       appProps.load(is);
       String appClassName = appProps.getProperty("plugin");
       Plugin plugin = instantiatePluginClass(appClassName);
       // lookup for artifact in the jars map
       if (jars != null) {
         // find URL of artifact
         boolean found = false;
         for (URI appUri : jars.keySet()) {
           if (propUrl.toExternalForm().startsWith("jar:" + appUri.toString())) {
             ArtifactApp app = new ArtifactApp(appUri.toURL(), jars.get(appUri), plugin);
             map.put(app.getCanonicalForm(), app);
             found = true;
           }
         }
         if (!found) {
           logger.warn("can't find artifact jar for " + propUrl + ", skipping");
         }
       }
     } catch (Exception e) {
       logger.warn("failed to load artifact from [" + propUrl + "]", e);
     } finally {
       if (is != null) {
         try {
           is.close();
         } catch (IOException e) {
           // ignore
         }
       }
     }
   }
   return map;
 }