package sbt.classpath

import java.lang.ref.{ Reference, SoftReference }
import java.util.HashMap

// Hack for testing only
private[sbt] final class ClassLoaderCache(val commonParent: ClassLoader) {
  private[this] val delegate = new HashMap[List[File], Reference[CachedClassLoader]]

   * Returns a ClassLoader with `commonParent` as a parent and that will load classes from classpath `files`.
   * The returned ClassLoader may be cached from a previous call if the last modified time of all `files` is unchanged.
   * This method is thread-safe.
  def apply(files: List[File]): ClassLoader = synchronized {
    val tstamps =
    getFromReference(files, tstamps, delegate.get(files))

  private[this] def getFromReference(files: List[File], stamps: List[Long], existingRef: Reference[CachedClassLoader]) =
    if (existingRef eq null)
      newEntry(files, stamps)
      get(files, stamps, existingRef.get)

  private[this] def get(files: List[File], stamps: List[Long], existing: CachedClassLoader): ClassLoader =
    if (existing == null || stamps != existing.timestamps) {
      newEntry(files, stamps)
    } else

  private[this] def newEntry(files: List[File], stamps: List[Long]): ClassLoader =
      val loader = new URLClassLoader(, commonParent)
      delegate.put(files, new SoftReference(new CachedClassLoader(loader, files, stamps)))
private[sbt] final class CachedClassLoader(val loader: ClassLoader, val files: List[File], val timestamps: List[Long])