public void nameClassLoader(Artifact artifactId, ClassLoader loader, boolean recursive) {
    DependentLoaderImplementation theLoader = null;
    theLoader = new DependentLoaderImplementation(artifactId, loader, exposed, parentLoader);

    if (artifactId != null) {
      assert (theLoader != null);
      setLoader(theLoader);
      assert (loaderMap.get(toString(artifactId)) != null);
    }
    if (recursive) {
      OutputBouble bouble = OutputBouble.push();

      try {
        List<Artifact> dependencies = dependencyManager.getDirectDependencies(artifactId);
        for (Artifact dependency : dependencies) {
          if (!loaderMap.containsKey(toString(dependency))) {
            nameClassLoader(dependency, theLoader, recursive);
          }
        }
      } catch (Exception e) {
        OutputBouble.reportError(e);
      } finally {
        bouble.pop();
        if (bouble.isError) bouble.writeToParent();
      }
    }
    visitLoader(theLoader);
  }
 private void visitLoader(DependentLoaderImplementation theLoader) {
   for (DependentLoaderVisitor v : visitors) {
     try {
       v.visitLoader(theLoader);
     } catch (Throwable e) {
       OutputBouble.reportError(e);
     }
   }
 }
 public void logGraph(String logFile) {
   PrintWriter writer;
   try {
     writer = new PrintWriter(logFile, "UTF-8");
     writer.println("digraph loaders {");
     for (Entry<String, DependentLoaderImplementation> inMap : loaderMap.entrySet()) {
       DependentLoaderImplementation loader = inMap.getValue();
       for (DependentLoaderImplementation depedent : loader.dependencies) {
         if (depedent != null)
           writer.println("\"" + loader.artifact + "\" -> " + "\"" + depedent.artifact + "\"");
         else writer.println("\"" + loader.artifact + "\" -> null");
       }
     }
     writer.println("}");
     writer.close();
   } catch (Exception e) {
     OutputBouble.reportError(e);
   }
 }
  public void getJar(Artifact artifactId) {
    OutputBouble bouble = OutputBouble.push();
    // Fetch jar and dependencies.
    try {
      Result<File> localFileName = dependencyManager.getLocalFile(artifactId);
      List<Artifact> dependencies = dependencyManager.getDirectDependencies(artifactId);

      int i = 0;
      for (Artifact dependencyId : dependencies) {
        if (!loaderMap.containsKey(toString(dependencyId))) {
          getJar(dependencyId);
        }
      }
    } catch (Exception e) {
      OutputBouble.reportError(e);
    } finally {
      bouble.pop();
      if (bouble.isError) bouble.writeToParent();
    }
  }
  public void unpack(String artifact, File destination) {
    File archiveFile = getAsFile(artifact);

    if (archiveFile == null || !archiveFile.exists()) return;
    if (archiveFile.isDirectory()) {
      try {
        Files.walkFileTree(archiveFile.toPath(), new CopyDirVisitor(archiveFile, destination));
      } catch (Exception e) {
        OutputBouble.reportError(e);
      }

    } else if (archiveFile.getName().endsWith("jar")) {
      destination.mkdirs();
      try {
        java.util.jar.JarFile jar = new java.util.jar.JarFile(archiveFile);
        java.util.Enumeration jarEnum = jar.entries();
        while (jarEnum.hasMoreElements()) {
          java.util.jar.JarEntry file = (java.util.jar.JarEntry) jarEnum.nextElement();
          java.io.File f = new java.io.File(destination + java.io.File.separator + file.getName());
          if (file.isDirectory()) { // if its a directory, create it
            f.mkdir();
            continue;
          }
          java.io.InputStream is = jar.getInputStream(file); // get the input stream
          java.io.FileOutputStream fos = new java.io.FileOutputStream(f);
          while (is.available() > 0) { // write contents of 'is' to 'fos'
            fos.write(is.read());
          }
          fos.close();
          is.close();
        }
        jar.close();
      } catch (Exception e) {

      }
    }
  }
  public void downloadFlat(String artifact, String copyToDir) {
    OutputBouble bouble = OutputBouble.push();
    try {
      Artifact theArtifact = new DefaultArtifact(artifact);

      HashSet<Artifact> downloadThese = new HashSet<Artifact>();
      downloadThese.add(theArtifact);
      Stack<Artifact> downloadDependenciesOfThese = new Stack<Artifact>();
      downloadDependenciesOfThese.add(theArtifact);

      while (!downloadDependenciesOfThese.isEmpty()) {
        Artifact getDependenciesOfThis = downloadDependenciesOfThese.pop();
        List<Artifact> dependencies =
            dependencyManager.getDirectDependencies(getDependenciesOfThis);
        for (Artifact a : dependencies) {
          if (!downloadThese.contains(a)) {
            downloadThese.add(a);
            downloadDependenciesOfThese.add(a);
          }
        }
      }

      File destination = new File(copyToDir);
      destination.mkdirs();

      for (Artifact a : downloadThese) {
        File theFile = getAsFile(a);
        Files.copy(theFile.toPath(), new File(destination, theFile.getName()).toPath());
      }
    } catch (Exception e) {
      OutputBouble.reportError(e);
    } finally {
      bouble.pop();
      if (bouble.isError) bouble.writeToParent();
    }
  }
  public DependentLoaderImplementation enshureJarLoaded(Artifact _artifactId) {
    Artifact artifactId = unify(_artifactId);

    if ("dependent".equals(artifactId.getArtifactId())
        && "no.dbwatch".equals(artifactId.getGroupId())) {
      return null;
    }
    DependentLoaderImplementation theLoader = findOverride(artifactId);
    if (theLoader != null) {
      visitLoader(theLoader);
      return theLoader;
    }
    if (loaderMap.containsKey(toString(artifactId))) return loaderMap.get(toString(artifactId));
    // Fetch jar and dependencies.
    OutputBouble bouble = OutputBouble.push();

    try {
      Result<File> localFileName = dependencyManager.getLocalFile(artifactId);

      if (localFileName.success())
        theLoader =
            new DependentLoaderImplementation(
                artifactId,
                localFileName.val.getAbsoluteFile().toURI().toURL(),
                exposed,
                parentLoader);
      else theLoader = new DependentLoaderImplementation(artifactId, exposed, parentLoader);
      setLoader(theLoader);

      List<Artifact> dependencies = dependencyManager.getDirectDependencies(artifactId);

      DependentLoaderImplementation[] actualDependencies =
          new DependentLoaderImplementation[dependencies.size() + theLoader.dependencies.length];
      int i = 0;
      for (DependentLoaderImplementation dependencyFromConf : theLoader.dependencies) {
        actualDependencies[i++] = dependencyFromConf;
      }
      for (Artifact dependencyId : dependencies) {

        DependentLoaderImplementation loader = enshureDependencyJarLoaded(artifactId, dependencyId);
        if (loader == null) {
          OutputBouble.logFile.println(artifactId.toString() + ":");
          OutputBouble.logFile.println("\t Missing dependency " + dependencyId.toString());
          OutputBouble.logFile.println("\t Ignoring");
        } else {
          actualDependencies[i++] = loader;
        }
      }
      if (actualDependencies.length > i) {
        actualDependencies = Arrays.copyOf(actualDependencies, i);
      }

      theLoader.setDependencies(actualDependencies);

      extraDependencies.loaderAdded(theLoader);

      visitLoader(theLoader);
      return theLoader;
    } catch (Exception e) {
      OutputBouble.reportError(e);
      return theLoader;
    } finally {
      bouble.pop();
      if (bouble.isError) bouble.writeToParent();
    }
    // return null;
  }