You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@clerezza.apache.org by re...@apache.org on 2013/12/04 16:21:26 UTC

[9/9] git commit: CLEREZZA-435: repaced tabs with spaces in scala files

CLEREZZA-435: repaced tabs with spaces in scala files

Project: http://git-wip-us.apache.org/repos/asf/clerezza/repo
Commit: http://git-wip-us.apache.org/repos/asf/clerezza/commit/35448624
Tree: http://git-wip-us.apache.org/repos/asf/clerezza/tree/35448624
Diff: http://git-wip-us.apache.org/repos/asf/clerezza/diff/35448624

Branch: refs/heads/master
Commit: 35448624b85f7bfaac87a7db202d2d68a555cbcc
Parents: a7d9d0f
Author: retobg <re...@apache.org>
Authored: Wed Dec 4 16:20:01 2013 +0100
Committer: retobg <re...@apache.org>
Committed: Wed Dec 4 16:20:01 2013 +0100

----------------------------------------------------------------------
 .../src/main/scala/Activator.scala              |    4 +-
 .../src/main/scala/HelloWorld.scala             |   20 +-
 .../main/scala/HelloWorldMessageRenderlet.scala |   26 +-
 .../src/main/scala/Ontology.scala               |    8 +-
 .../clerezza/bundledevtool/BundleRoot.scala     |  502 +++----
 .../apache/clerezza/bundledevtool/DevDsl.scala  |  116 +-
 .../bundledevtool/DevShellCustomizer.scala      |   10 +-
 .../PermissionGrantingPathNode.scala            |    8 +-
 .../UnavailableSkeletonException.scala          |    2 +-
 .../src/main/scala/sbt/ErrorHandling.scala      |   30 +-
 bundledevtool/src/main/scala/sbt/io/Hash.scala  |  130 +-
 bundledevtool/src/main/scala/sbt/io/IO.scala    | 1138 +++++++--------
 bundledevtool/src/main/scala/sbt/io/IPC.scala   |  116 +-
 .../src/main/scala/sbt/io/NameFilter.scala      |   60 +-
 bundledevtool/src/main/scala/sbt/io/Pack.scala  |  120 +-
 bundledevtool/src/main/scala/sbt/io/Path.scala  |  704 +++++-----
 .../src/main/scala/sbt/io/PathMapper.scala      |   84 +-
 .../src/main/scala/sbt/io/Resources.scala       |   98 +-
 .../scala/sbt/io/SourceModificationWatch.scala  |   62 +-
 bundledevtool/src/main/scala/sbt/io/Using.scala |  130 +-
 .../webfragements/WebFragmentRunner.scala       |   64 +-
 .../osgi/services/ActivationHelper.scala        |  142 +-
 .../clerezza/osgi/services/ServicesDsl.scala    |  134 +-
 .../AcpPermissionDescriptionsProvider.scala     |   58 +-
 .../accountcontrolpanel/MenuItemProvider.scala  |   48 +-
 .../accountcontrolpanel/ProfilePanel.scala      |  794 +++++------
 .../accountcontrolpanel/SettingsPanel.scala     | 1026 +++++++-------
 .../html/ContactConfirmRenderlet.scala          |  136 +-
 .../accountcontrolpanel/html/PersonBox.scala    |   56 +-
 .../accountcontrolpanel/html/ProfilePanel.scala |  514 +++----
 .../html/RenderingUtility.scala                 |   92 +-
 .../html/SettingsPanel.scala                    |  210 +--
 .../accountcontrolpanel/permissions.scala       |   66 +-
 .../default404/DefaultPageNotFoundService.scala |   48 +-
 .../content/fsadaptor/BundleFsLoader.scala      |  472 +++----
 .../content/fsadaptor/DirectoryOverlay.scala    |   88 +-
 .../platform/content/fsadaptor/Logger.scala     |    4 +-
 .../content/fsadaptor/PathNode2MGraph.scala     |  192 +--
 .../renderlets/HtmlInfoDicobitRDFaNaked.scala   |   16 +-
 .../renderlets/OrderedContentRDFaNaked.scala    |   16 +-
 .../renderlets/TitledContentRDFaNaked.scala     |   16 +-
 .../graphnodeprovider/GraphNodeProvider.scala   |  350 ++---
 .../logging/initializer/Activator.scala         |   90 +-
 .../foafssl/auth/FoafSslAuthentication.scala    |   16 +-
 .../clerezza/foafssl/auth/WebIDClaim.scala      |  294 ++--
 .../clerezza/foafssl/auth/X509Claim.scala       |   22 +-
 .../apache/clerezza/foafssl/ssl/Activator.scala |   90 +-
 .../ssl/X509TrustManagerWrapperService.scala    |   50 +-
 .../clerezza/foafssl/test/WebIDTester.scala     | 1306 +++++++++---------
 .../foafssl/test/pages/WebIDClaimPg.scala       |  208 +--
 .../platform/shellcustomizer/PlatformDsl.scala  |   18 +-
 .../src/main/scala/Activator.scala              |   10 +-
 .../src/main/scala/CollectionHeader.scala       |    4 +-
 .../src/main/scala/GlobalMenuRenderlet.scala    |   86 +-
 .../src/main/scala/HeadedPageRenderlet.scala    |  210 +--
 .../src/main/scala/RdfListRenderlet.scala       |   30 +-
 .../src/main/scala/Activator.scala              |  150 +-
 .../src/main/scala/Ontology.scala               |   18 +-
 .../scala/RenderletDescriptionRenderlet.scala   |   34 +-
 .../typerendering/scala/AbstractRenderlet.scala |   62 +-
 .../typerendering/scala/PageRenderlet.scala     |   32 +-
 .../typerendering/scala/RenderedPage.scala      |  230 +--
 .../typerendering/scala/SRenderlet.scala        |   58 +-
 .../typerendering/scala/XmlResult.scala         |  226 +--
 .../UserGraphAcessPermissionProvider.scala      |   28 +-
 .../platform/users/WebIdGraphsService.scala     |  328 ++---
 .../clerezza/platform/users/WebIdInfo.scala     |   52 +-
 .../rdf/scala/utils/CollectedIter.scala         |  114 +-
 .../clerezza/rdf/scala/utils/EzLiteral.scala    |   34 +-
 .../clerezza/rdf/scala/utils/EzMGraph.scala     |   76 +-
 .../clerezza/rdf/scala/utils/NameSpace.scala    |   16 +-
 .../clerezza/rdf/scala/utils/Preamble.scala     |   64 +-
 .../rdf/scala/utils/RichGraphNode.scala         |  386 +++---
 .../clerezza/rdf/scala/utils/EzMGraphTest.scala |  224 +--
 .../rdf/scala/utils/RichGraphNodeTest.scala     |  268 ++--
 .../rdf/scala/utils/TypeConversionTest.scala    |   70 +-
 rdf.storage.web/src/main/scala/WebProxy.scala   |  444 +++---
 .../scripting/BundleContextScalaCompiler.scala  |   50 +-
 .../BundleContextScalaInterpreter.scala         |   22 +-
 .../clerezza/scala/scripting/BundleFS.scala     |  308 ++---
 .../scala/scripting/CompilerService.scala       |    2 +-
 .../scala/scripting/InterpreterFactory.scala    |   28 +-
 .../scala/scripting/ScriptEngineFactory.scala   |  474 +++----
 .../scala/scripting/TrackingCompiler.scala      |  150 +-
 .../scala/scripting/util/FileWrapper.scala      |   26 +-
 .../util/GenericFileWrapperTrait.scala          |  112 +-
 .../scripting/util/SplittingDirectory.scala     |   82 +-
 .../util/VirtualDirectoryWrapper.scala          |  108 +-
 .../clerezza/scala/scripting/util/Wrapper.scala |    4 +-
 .../scala/tests/CompilerServiceTest.scala       |  324 ++---
 .../scala/tests/ScriptEngineFactoryTest.scala   |  294 ++--
 .../felixshellcommand/FelixShellCommand.scala   |   42 +-
 .../apache/clerezza/shell/ConsoleShell.scala    |   96 +-
 .../shell/InterruptibleInputStream.scala        |   76 +-
 .../scala/org/apache/clerezza/shell/Shell.scala |    6 +-
 .../apache/clerezza/shell/ShellCommand.scala    |   12 +-
 .../apache/clerezza/shell/ShellCustomizer.scala |   18 +-
 .../apache/clerezza/shell/ShellPermission.scala |   20 +-
 site/src/main/scala/Activator.scala             |  134 +-
 site/src/main/scala/GlobalMenuRenderlet.scala   |   86 +-
 site/src/main/scala/HeadedPageRenderlet.scala   |  196 +--
 site/src/main/scala/Ontology.scala              |    8 +-
 .../src/main/scala/TitledContentRenderlet.scala |  238 ++--
 103 files changed, 8087 insertions(+), 8087 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/clerezza/blob/35448624/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/Activator.scala
----------------------------------------------------------------------
diff --git a/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/Activator.scala b/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/Activator.scala
index 6390a35..3e9a4be 100644
--- a/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/Activator.scala
+++ b/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/Activator.scala
@@ -27,6 +27,6 @@ import org.apache.clerezza.osgi.services.ActivationHelper
  * Activator for a bundle using Apache Clerezza.
  */
 class Activator extends ActivationHelper {
-	registerRootResource(new HelloWorld(context))
-	registerRenderlet(new HelloWorldMessageRenderlet)
+  registerRootResource(new HelloWorld(context))
+  registerRenderlet(new HelloWorldMessageRenderlet)
 }

http://git-wip-us.apache.org/repos/asf/clerezza/blob/35448624/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/HelloWorld.scala
----------------------------------------------------------------------
diff --git a/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/HelloWorld.scala b/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/HelloWorld.scala
index 3980bbc..e45976a 100644
--- a/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/HelloWorld.scala
+++ b/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/HelloWorld.scala
@@ -35,15 +35,15 @@ import org.apache.clerezza.platform.graphprovider.content.ContentGraphProvider
  */
 @Path("hello-world")
 class HelloWorld(context: BundleContext) {
-	val servicesDsl = new ServicesDsl(context)
-	import servicesDsl._
-	@GET def get() = {
-		val resultMGraph = new SimpleMGraph();
-		val graphNode = new GraphNode(new BNode(), resultMGraph);
-		graphNode.addProperty(RDF.`type` , Ontology.HelloWordMessageType);
-		val cgp: ContentGraphProvider = $[ContentGraphProvider]
-		graphNode.addPropertyValue(DC.description,"Hello world of "+cgp.getContentGraph.size);
-		graphNode;
+  val servicesDsl = new ServicesDsl(context)
+  import servicesDsl._
+  @GET def get() = {
+    val resultMGraph = new SimpleMGraph();
+    val graphNode = new GraphNode(new BNode(), resultMGraph);
+    graphNode.addProperty(RDF.`type` , Ontology.HelloWordMessageType);
+    val cgp: ContentGraphProvider = $[ContentGraphProvider]
+    graphNode.addPropertyValue(DC.description,"Hello world of "+cgp.getContentGraph.size);
+    graphNode;
 
-	}
+  }
 }

http://git-wip-us.apache.org/repos/asf/clerezza/blob/35448624/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/HelloWorldMessageRenderlet.scala
----------------------------------------------------------------------
diff --git a/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/HelloWorldMessageRenderlet.scala b/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/HelloWorldMessageRenderlet.scala
index 04da6de..6e41732 100644
--- a/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/HelloWorldMessageRenderlet.scala
+++ b/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/HelloWorldMessageRenderlet.scala
@@ -37,20 +37,20 @@ import org.apache.clerezza.rdf.ontologies.DC
  */
 class HelloWorldMessageRenderlet extends SRenderlet {
 
-	val getRdfType = Ontology.HelloWordMessageType
+  val getRdfType = Ontology.HelloWordMessageType
 
-	override def getModePattern = "naked"
+  override def getModePattern = "naked"
 
-	override def renderedPage(arguments: XmlResult.Arguments) = {
-		new XmlResult(arguments) {
-			override def content = {
-				resultDocModifier.addStyleSheet("/styles/hello-world/style.css")
-				<div xmlns="http://www.w3.org/1999/xhtml" id="tx-content">
-					<h2>A Message</h2>
-					<div class="message">{res/DC.description*}</div>
-				</div>
-			}
-		}
-	}
+  override def renderedPage(arguments: XmlResult.Arguments) = {
+    new XmlResult(arguments) {
+      override def content = {
+        resultDocModifier.addStyleSheet("/styles/hello-world/style.css")
+        <div xmlns="http://www.w3.org/1999/xhtml" id="tx-content">
+          <h2>A Message</h2>
+          <div class="message">{res/DC.description*}</div>
+        </div>
+      }
+    }
+  }
 
 }

http://git-wip-us.apache.org/repos/asf/clerezza/blob/35448624/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/Ontology.scala
----------------------------------------------------------------------
diff --git a/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/Ontology.scala b/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/Ontology.scala
index 924df22..c831e8e 100644
--- a/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/Ontology.scala
+++ b/bundledevtool/src/main/resources/org/apache/clerezza/bundledevtool/skeletons/scala_with_activator/src/main/scala/Ontology.scala
@@ -25,9 +25,9 @@ import org.apache.clerezza.rdf.core.UriRef
 
 object Ontology {
 
-	/**
-	 * The uri for the RDF type of HelloWordMessage
-	 */
-	val HelloWordMessageType = new UriRef("http://example.org/skeleton#HelloWordMessage")
+  /**
+   * The uri for the RDF type of HelloWordMessage
+   */
+  val HelloWordMessageType = new UriRef("http://example.org/skeleton#HelloWordMessage")
 
 }

http://git-wip-us.apache.org/repos/asf/clerezza/blob/35448624/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/BundleRoot.scala
----------------------------------------------------------------------
diff --git a/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/BundleRoot.scala b/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/BundleRoot.scala
index 0186850..51cb6f8 100644
--- a/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/BundleRoot.scala
+++ b/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/BundleRoot.scala
@@ -48,261 +48,261 @@ import org.wymiwyg.commons.util.dirbrowser.{PathNode, FilePathNode}
  */
 class BundleRoot {
 
-	private var compilerService: CompilerService = null
-	private var packageAdmin: PackageAdmin = null
-
-	private var bundleContext: BundleContext = null
-
-	private val skeletonsPath = "org/apache/clerezza/bundledevtool/skeletons"
-
-	val sourceBundles = mutable.ListBuffer[SourceBundle]()
-
-	protected def activate(c: ComponentContext) {
-		this.bundleContext = c.getBundleContext
-		sourceBundles.clear()
-		for (bundle <- bundleContext.getBundles) {
-			val location = bundle.getLocation
-			if (location.startsWith(BundleRoot.sourceBundleUriPrefix)) {
-				val dir = new File(location.substring(
-						BundleRoot.sourceBundleUriPrefix.length))
-				//TODO encode fileFastUpdate in location
-				val sourceBundle = new SourceBundle(dir, bundle, true)
-				sourceBundle.start()
-				sourceBundles += sourceBundle
-			}
-		}
-	}
-
-	protected def deactivate(c: ComponentContext) {
-		for (sb <- sourceBundles) sb.stop()
-	}
-
-	/**
-	 * adds a SourceBundle for the sources in the specified dir
-	 */
-	def addSourceBundle(dir: File, fileFastUpdate: Boolean) = {
-		val sourceBundle = new SourceBundle(dir, fileFastUpdate)
-		sourceBundle.start()
-		sourceBundles += sourceBundle
-		sourceBundle
-	}
-
-
-	/**
-	* list of the available skletons
-	*/
-	def availableSkeletons: Seq[Symbol] = {
-		val skeletonsNode = new BundlePathNode(bundleContext.getBundle, skeletonsPath)
-		for (name <- skeletonsNode.list) yield {
-			Symbol(name.substring(1,name.length-1))
-		}
-	}
-
-	/**
-	 * Creates and adds a new SourceBundle from a skeleton, no existing file is
-	 * replaced
-	 */
-	def createSourceBundle(skeleton: Symbol, dir: File) = {
-		dir.mkdirs
-		val skeletonsNode = new BundlePathNode(bundleContext.getBundle, skeletonsPath)
-		val skeletonNode = skeletonsNode.getSubPath(skeleton.name)
-		if (!skeletonNode.exists) {
-			throw new UnavailableSkeletonException(skeleton, availableSkeletons)
-		}
-		def processFile(p: PathNode, f: File) {
-			if (!f.exists) {
-				val in = scala.io.Source.fromInputStream(p.getInputStream)
-				val out = new java.io.PrintWriter(f)
-				try { in.getLines().foreach(out.println(_)) }
-				finally { out.close }
-			}
-		}
-		def processDir(p: PathNode, f: File) {
-			f.mkdir()
-			for (subPathString <- p.list()) {
-				val subPathNode: PathNode = p.getSubPath(subPathString)
-				val subFile: File = new File(f, subPathString)
-				if (subPathNode.isDirectory) {
-					processDir(subPathNode, subFile)
-				} else {
-					processFile(subPathNode, subFile)
-				}
-			}
-		}
-
-		processDir(skeletonNode, dir)
-		addSourceBundle(dir, true)
-	}
-
-	def bindCompilerService(cs: CompilerService) {
-		compilerService = cs;
-	}
-
-	def unbindCompilerService(cs: CompilerService) {
-		compilerService = null;
-	}
-
-	def bindPackageAdmin(pa: PackageAdmin) {
-		packageAdmin = pa
-	}
-
-	def unbindPackageAdmin(pa: PackageAdmin) {
-		packageAdmin = null
-	}
-
-	class SourceBundle(dir: File, existingBundle: Bundle, fileFastUpdate: Boolean) extends DaemonActor {
-
-		def this(dir: File, fileFastUpdate: Boolean) {
-			this(dir, null, fileFastUpdate)
-		}
-
-		var stopped = false
-		var logger = LoggerFactory.getLogger(classOf[SourceBundle])
-
-		val sourcePath = Path.fromFile(new File(dir,"src"))
-		var watchState = WatchState.empty
-		var bundle: Bundle = existingBundle
-		if (fileFastUpdate) {
-			val pathNode = new PermissionGrantingPathNode(new FilePathNode(new File(dir,"src/main/resources/CLEREZZA-INF/web-resources/")))
-			val registration = bundleContext.registerService(Array(classOf[PathNode].getName), pathNode, null: java.util.Dictionary[String, _])
-			//println("registered "+classOf[PathNode].getName+": "+registration)
-		}
-		
-		def getFilesAsCharArrays(file: File): List[Array[Char]] = {
-			logger.debug("getting sources in "+file)
-			var result: List[Array[Char]] = Nil
-			if (file.isDirectory) {
-				val children = file.listFiles
-				import scala.collection.JavaConversions._
-				for(child <- children) {
-					if (!child.getName.startsWith(".")) {
-						result = getFilesAsCharArrays(child) ::: result
-					}
-				}
-			} else {
-				if (file.getName.endsWith(".scala")) {
-					val in = Source.fromFile(file, "utf-8")
-					val stream = in.toStream
-					result = stream.toArray :: result
-				} 
-			}
-			result
-		}
-
-		private[this] def updateBundle() {
-			logger.info("updating source bundle with root "+dir)
-
-			val tinyBundle: TinyBundle = newBundle()
-
-			def compileDir(sourceDir: File): Option[String] = {
-
-				val charArrays = getFilesAsCharArrays(sourceDir)
-				logger.debug("compiling "+charArrays.size+" files")
-
-				val vdPathPrefix = "(memory)"
-				val virtualDirectory = new VirtualDirectory(vdPathPrefix, None)
-				//val wrappedDirectory = VirtualDirectoryWrapper.wrap(virtualDirectory, outputListener)
-
-				val writtenClasses = compilerService.compileToDir(charArrays, virtualDirectory)
-				logger.debug("virtualDirectory "+virtualDirectory.size)
-				var potentialActivator: Option[String] = None
-				for (writtenClass <- writtenClasses) {
-					val fullPath = writtenClass.path
-					val path = fullPath.substring(vdPathPrefix.length+1)
-					if (path.endsWith("Activator.class")) {
-						potentialActivator = Some(path.substring(0, path.lastIndexOf('.')).replace('/', '.'))
-					}
-					tinyBundle.add(path, new ByteArrayInputStream(writtenClass.toByteArray))
-				}
-		    potentialActivator
-			}
-
-			def copyResource(resourcesDir: File) {
-				def copyResource(resourcesDir: File, prefix: String) {
-					val children = resourcesDir.listFiles
-					import scala.collection.JavaConversions._
-					for(child <- children) {
-						val childName = child.getName
-						if (!childName.startsWith(".")) {
-							if (child.isDirectory) {
-								copyResource(child, prefix+childName+"/")
-							} else {
-								tinyBundle.add(prefix+childName, new FileInputStream(child))
-							}
-						}
-					}
-				}
-				copyResource(resourcesDir, "")
-			}
-
-			val symName = dir.getPath.substring(1).replace(File.separatorChar, '.')
-
-			tinyBundle.set("Bundle-SymbolicName", symName)
-
-			val scalaSourceDir = new File(dir, "src/main/scala")
-
-			val potentialActivator = if (scalaSourceDir.exists) {
-				compileDir(scalaSourceDir)
-			} else {
-				logger.debug("No source dir "+scalaSourceDir)
-				None
-			}
-			val resourcesDir = new File(dir, "src/main/resources")
-			if (resourcesDir.exists) {
-				copyResource(resourcesDir)
-			} else {
-				logger.debug("No resources dir "+resourcesDir)
-			}
-			val serviceComponentsFile = new File(resourcesDir, "OSGI-INF/serviceComponents.xml")
-			if (serviceComponentsFile.exists) {
-				tinyBundle.set("Service-Component", "OSGI-INF/serviceComponents.xml")
-				tinyBundle.set(Constants.EXPORT_PACKAGE, "!OSGI-INF, *" )
-			}
-			potentialActivator match {
-				case Some(s) =>  tinyBundle.set("Bundle-Activator", s)
-				case _ => ;
-			}
-			tinyBundle.set(Constants.IMPORT_PACKAGE, "*" );
-			val in = tinyBundle.build(
-					withBnd()
-				)
-
-
-			if (bundle == null) {
-				bundle = bundleContext.installBundle(BundleRoot.sourceBundleUriPrefix+dir.toString, in)
-				bundle.start()
-			} else {
-				bundle.update(in)
-			}
-
-		}
-
-		def act() {
-			while (!stopped) {
-				logger.debug("wathcing "+dir)
-				val (triggered, newWatchState) =
-					SourceModificationWatch.watch(sourcePath**(-HiddenFileFilter), 1, watchState)(stopped)
-				logger.debug("watching got "+triggered+", "+newWatchState)
-				if (!stopped) {
-					try {
-						updateBundle()
-					} catch {
-						case e => logger.warn("Exception compiling", e)
-					}
-					watchState = newWatchState
-				}
-			}
-		}
-
-		def stop() {
-			stopped = true
-		}
-	}
+  private var compilerService: CompilerService = null
+  private var packageAdmin: PackageAdmin = null
+
+  private var bundleContext: BundleContext = null
+
+  private val skeletonsPath = "org/apache/clerezza/bundledevtool/skeletons"
+
+  val sourceBundles = mutable.ListBuffer[SourceBundle]()
+
+  protected def activate(c: ComponentContext) {
+    this.bundleContext = c.getBundleContext
+    sourceBundles.clear()
+    for (bundle <- bundleContext.getBundles) {
+      val location = bundle.getLocation
+      if (location.startsWith(BundleRoot.sourceBundleUriPrefix)) {
+        val dir = new File(location.substring(
+            BundleRoot.sourceBundleUriPrefix.length))
+        //TODO encode fileFastUpdate in location
+        val sourceBundle = new SourceBundle(dir, bundle, true)
+        sourceBundle.start()
+        sourceBundles += sourceBundle
+      }
+    }
+  }
+
+  protected def deactivate(c: ComponentContext) {
+    for (sb <- sourceBundles) sb.stop()
+  }
+
+  /**
+   * adds a SourceBundle for the sources in the specified dir
+   */
+  def addSourceBundle(dir: File, fileFastUpdate: Boolean) = {
+    val sourceBundle = new SourceBundle(dir, fileFastUpdate)
+    sourceBundle.start()
+    sourceBundles += sourceBundle
+    sourceBundle
+  }
+
+
+  /**
+  * list of the available skletons
+  */
+  def availableSkeletons: Seq[Symbol] = {
+    val skeletonsNode = new BundlePathNode(bundleContext.getBundle, skeletonsPath)
+    for (name <- skeletonsNode.list) yield {
+      Symbol(name.substring(1,name.length-1))
+    }
+  }
+
+  /**
+   * Creates and adds a new SourceBundle from a skeleton, no existing file is
+   * replaced
+   */
+  def createSourceBundle(skeleton: Symbol, dir: File) = {
+    dir.mkdirs
+    val skeletonsNode = new BundlePathNode(bundleContext.getBundle, skeletonsPath)
+    val skeletonNode = skeletonsNode.getSubPath(skeleton.name)
+    if (!skeletonNode.exists) {
+      throw new UnavailableSkeletonException(skeleton, availableSkeletons)
+    }
+    def processFile(p: PathNode, f: File) {
+      if (!f.exists) {
+        val in = scala.io.Source.fromInputStream(p.getInputStream)
+        val out = new java.io.PrintWriter(f)
+        try { in.getLines().foreach(out.println(_)) }
+        finally { out.close }
+      }
+    }
+    def processDir(p: PathNode, f: File) {
+      f.mkdir()
+      for (subPathString <- p.list()) {
+        val subPathNode: PathNode = p.getSubPath(subPathString)
+        val subFile: File = new File(f, subPathString)
+        if (subPathNode.isDirectory) {
+          processDir(subPathNode, subFile)
+        } else {
+          processFile(subPathNode, subFile)
+        }
+      }
+    }
+
+    processDir(skeletonNode, dir)
+    addSourceBundle(dir, true)
+  }
+
+  def bindCompilerService(cs: CompilerService) {
+    compilerService = cs;
+  }
+
+  def unbindCompilerService(cs: CompilerService) {
+    compilerService = null;
+  }
+
+  def bindPackageAdmin(pa: PackageAdmin) {
+    packageAdmin = pa
+  }
+
+  def unbindPackageAdmin(pa: PackageAdmin) {
+    packageAdmin = null
+  }
+
+  class SourceBundle(dir: File, existingBundle: Bundle, fileFastUpdate: Boolean) extends DaemonActor {
+
+    def this(dir: File, fileFastUpdate: Boolean) {
+      this(dir, null, fileFastUpdate)
+    }
+
+    var stopped = false
+    var logger = LoggerFactory.getLogger(classOf[SourceBundle])
+
+    val sourcePath = Path.fromFile(new File(dir,"src"))
+    var watchState = WatchState.empty
+    var bundle: Bundle = existingBundle
+    if (fileFastUpdate) {
+      val pathNode = new PermissionGrantingPathNode(new FilePathNode(new File(dir,"src/main/resources/CLEREZZA-INF/web-resources/")))
+      val registration = bundleContext.registerService(Array(classOf[PathNode].getName), pathNode, null: java.util.Dictionary[String, _])
+      //println("registered "+classOf[PathNode].getName+": "+registration)
+    }
+    
+    def getFilesAsCharArrays(file: File): List[Array[Char]] = {
+      logger.debug("getting sources in "+file)
+      var result: List[Array[Char]] = Nil
+      if (file.isDirectory) {
+        val children = file.listFiles
+        import scala.collection.JavaConversions._
+        for(child <- children) {
+          if (!child.getName.startsWith(".")) {
+            result = getFilesAsCharArrays(child) ::: result
+          }
+        }
+      } else {
+        if (file.getName.endsWith(".scala")) {
+          val in = Source.fromFile(file, "utf-8")
+          val stream = in.toStream
+          result = stream.toArray :: result
+        } 
+      }
+      result
+    }
+
+    private[this] def updateBundle() {
+      logger.info("updating source bundle with root "+dir)
+
+      val tinyBundle: TinyBundle = newBundle()
+
+      def compileDir(sourceDir: File): Option[String] = {
+
+        val charArrays = getFilesAsCharArrays(sourceDir)
+        logger.debug("compiling "+charArrays.size+" files")
+
+        val vdPathPrefix = "(memory)"
+        val virtualDirectory = new VirtualDirectory(vdPathPrefix, None)
+        //val wrappedDirectory = VirtualDirectoryWrapper.wrap(virtualDirectory, outputListener)
+
+        val writtenClasses = compilerService.compileToDir(charArrays, virtualDirectory)
+        logger.debug("virtualDirectory "+virtualDirectory.size)
+        var potentialActivator: Option[String] = None
+        for (writtenClass <- writtenClasses) {
+          val fullPath = writtenClass.path
+          val path = fullPath.substring(vdPathPrefix.length+1)
+          if (path.endsWith("Activator.class")) {
+            potentialActivator = Some(path.substring(0, path.lastIndexOf('.')).replace('/', '.'))
+          }
+          tinyBundle.add(path, new ByteArrayInputStream(writtenClass.toByteArray))
+        }
+        potentialActivator
+      }
+
+      def copyResource(resourcesDir: File) {
+        def copyResource(resourcesDir: File, prefix: String) {
+          val children = resourcesDir.listFiles
+          import scala.collection.JavaConversions._
+          for(child <- children) {
+            val childName = child.getName
+            if (!childName.startsWith(".")) {
+              if (child.isDirectory) {
+                copyResource(child, prefix+childName+"/")
+              } else {
+                tinyBundle.add(prefix+childName, new FileInputStream(child))
+              }
+            }
+          }
+        }
+        copyResource(resourcesDir, "")
+      }
+
+      val symName = dir.getPath.substring(1).replace(File.separatorChar, '.')
+
+      tinyBundle.set("Bundle-SymbolicName", symName)
+
+      val scalaSourceDir = new File(dir, "src/main/scala")
+
+      val potentialActivator = if (scalaSourceDir.exists) {
+        compileDir(scalaSourceDir)
+      } else {
+        logger.debug("No source dir "+scalaSourceDir)
+        None
+      }
+      val resourcesDir = new File(dir, "src/main/resources")
+      if (resourcesDir.exists) {
+        copyResource(resourcesDir)
+      } else {
+        logger.debug("No resources dir "+resourcesDir)
+      }
+      val serviceComponentsFile = new File(resourcesDir, "OSGI-INF/serviceComponents.xml")
+      if (serviceComponentsFile.exists) {
+        tinyBundle.set("Service-Component", "OSGI-INF/serviceComponents.xml")
+        tinyBundle.set(Constants.EXPORT_PACKAGE, "!OSGI-INF, *" )
+      }
+      potentialActivator match {
+        case Some(s) =>  tinyBundle.set("Bundle-Activator", s)
+        case _ => ;
+      }
+      tinyBundle.set(Constants.IMPORT_PACKAGE, "*" );
+      val in = tinyBundle.build(
+          withBnd()
+        )
+
+
+      if (bundle == null) {
+        bundle = bundleContext.installBundle(BundleRoot.sourceBundleUriPrefix+dir.toString, in)
+        bundle.start()
+      } else {
+        bundle.update(in)
+      }
+
+    }
+
+    def act() {
+      while (!stopped) {
+        logger.debug("wathcing "+dir)
+        val (triggered, newWatchState) =
+          SourceModificationWatch.watch(sourcePath**(-HiddenFileFilter), 1, watchState)(stopped)
+        logger.debug("watching got "+triggered+", "+newWatchState)
+        if (!stopped) {
+          try {
+            updateBundle()
+          } catch {
+            case e => logger.warn("Exception compiling", e)
+          }
+          watchState = newWatchState
+        }
+      }
+    }
+
+    def stop() {
+      stopped = true
+    }
+  }
 }
 
 
 object BundleRoot {
 
-	val sourceBundleUriPrefix = "bundledevtool:"
+  val sourceBundleUriPrefix = "bundledevtool:"
 
 }

http://git-wip-us.apache.org/repos/asf/clerezza/blob/35448624/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/DevDsl.scala
----------------------------------------------------------------------
diff --git a/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/DevDsl.scala b/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/DevDsl.scala
index 13df54c..f69eef7 100644
--- a/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/DevDsl.scala
+++ b/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/DevDsl.scala
@@ -28,66 +28,66 @@ import org.apache.clerezza.osgi.services.ServicesDsl
 
 class DevDsl(outputStream: OutputStream, bundleContext: BundleContext) {
 
-	sealed class FastUpdateMode;
+  sealed class FastUpdateMode;
   
-	var fastUpdate = new FastUpdateMode;
-	var noFastUpdate = new FastUpdateMode();
-	
-	case class LocationSpec(location: String, fastUpdateMode: FastUpdateMode) {
-		def this(location: String) {
-		  this(location, fastUpdate)
-		}
-	}
-	
-	implicit def locationSpecBuilder(location: String) = new LocationSpec(location)
-	
-	object Dev {
-		private val serviceDsl = new ServicesDsl(bundleContext)
-		import serviceDsl._
-		private lazy val out = new PrintWriter(new OutputStreamWriter(outputStream, "utf-8"), true)
+  var fastUpdate = new FastUpdateMode;
+  var noFastUpdate = new FastUpdateMode();
+  
+  case class LocationSpec(location: String, fastUpdateMode: FastUpdateMode) {
+    def this(location: String) {
+      this(location, fastUpdate)
+    }
+  }
+  
+  implicit def locationSpecBuilder(location: String) = new LocationSpec(location)
+  
+  object Dev {
+    private val serviceDsl = new ServicesDsl(bundleContext)
+    import serviceDsl._
+    private lazy val out = new PrintWriter(new OutputStreamWriter(outputStream, "utf-8"), true)
 
-		def listArchetypes() {
-			out println "The following archetypes are available"
-			for (a <- $[BundleRoot].availableSkeletons) {
-				out println "  - "+a
-			}
-		}
-		
-		def create(archetype: Symbol) = new Object() {
-			def in(location: String): Unit = try {
-				$[BundleRoot].createSourceBundle(archetype, new File(location))
-			} catch {
-				case u: UnavailableSkeletonException => {
-					out println "FAILURE: no archetype "+archetype+" is available"
-					listArchetypes()
-				}
-			}
-		}
+    def listArchetypes() {
+      out println "The following archetypes are available"
+      for (a <- $[BundleRoot].availableSkeletons) {
+        out println "  - "+a
+      }
+    }
+    
+    def create(archetype: Symbol) = new Object() {
+      def in(location: String): Unit = try {
+        $[BundleRoot].createSourceBundle(archetype, new File(location))
+      } catch {
+        case u: UnavailableSkeletonException => {
+          out println "FAILURE: no archetype "+archetype+" is available"
+          listArchetypes()
+        }
+      }
+    }
 
-		def load(locationSpec: LocationSpec) {
-			val dir = new File(locationSpec.location)
-			if (!dir.isDirectory) {
-				out println "No directory "+locationSpec.location+" found"
-			} else {
-				$[BundleRoot].addSourceBundle(dir, locationSpec.fastUpdateMode == fastUpdate)
-			}
-		}
-		
-		def help() {
-		  out println "The Dev utitly can be used as follows:"
-		  out println "Dev listArchetypes"
-		  out println "\tlists the available archetypes"
-		  out println "Dev create <archetype-name> in \"/path/to/directory\""
-		  out println "\tCreates a new project in /path/to/directory using the specified archetype"
-		  out println "Dev load \"/path/to/directory\""
-		  out println "\tLoads the project in /path/to/directory"
-		  out println "Dev load \"/path/to/directory\""
-		  out println "\tLoads the project in /path/to/directory enabling fast-updating of static files"
-		  out println "Dev load LocationSpec(\"/path/to/directory\",fastUpdate|noFastUpdate)"
-		  out println "\tLoads the project in /path/to/directory enabling or diabling fast-updating of static files"
-		}
-		
-		override def toString = "Run 'Dev help' for usage instructions"
-	}
+    def load(locationSpec: LocationSpec) {
+      val dir = new File(locationSpec.location)
+      if (!dir.isDirectory) {
+        out println "No directory "+locationSpec.location+" found"
+      } else {
+        $[BundleRoot].addSourceBundle(dir, locationSpec.fastUpdateMode == fastUpdate)
+      }
+    }
+    
+    def help() {
+      out println "The Dev utitly can be used as follows:"
+      out println "Dev listArchetypes"
+      out println "\tlists the available archetypes"
+      out println "Dev create <archetype-name> in \"/path/to/directory\""
+      out println "\tCreates a new project in /path/to/directory using the specified archetype"
+      out println "Dev load \"/path/to/directory\""
+      out println "\tLoads the project in /path/to/directory"
+      out println "Dev load \"/path/to/directory\""
+      out println "\tLoads the project in /path/to/directory enabling fast-updating of static files"
+      out println "Dev load LocationSpec(\"/path/to/directory\",fastUpdate|noFastUpdate)"
+      out println "\tLoads the project in /path/to/directory enabling or diabling fast-updating of static files"
+    }
+    
+    override def toString = "Run 'Dev help' for usage instructions"
+  }
 
 }

http://git-wip-us.apache.org/repos/asf/clerezza/blob/35448624/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/DevShellCustomizer.scala
----------------------------------------------------------------------
diff --git a/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/DevShellCustomizer.scala b/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/DevShellCustomizer.scala
index 05cc7f9..2acaa8c 100644
--- a/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/DevShellCustomizer.scala
+++ b/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/DevShellCustomizer.scala
@@ -22,9 +22,9 @@ import org.apache.clerezza.shell.Shell
 import org.apache.clerezza.shell.ShellCustomizer
 
 class DevShellCustomizer extends ShellCustomizer {
-	def bindings(e: Shell.Environment): List[(String, String, Any)] = {
-		List(("devDsl", classOf[DevDsl].getName, new DevDsl(e.out,
-						e.componentContext.getBundleContext)))
-	}
-	def imports: List[String] = List("devDsl._")
+  def bindings(e: Shell.Environment): List[(String, String, Any)] = {
+    List(("devDsl", classOf[DevDsl].getName, new DevDsl(e.out,
+            e.componentContext.getBundleContext)))
+  }
+  def imports: List[String] = List("devDsl._")
 }

http://git-wip-us.apache.org/repos/asf/clerezza/blob/35448624/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/PermissionGrantingPathNode.scala
----------------------------------------------------------------------
diff --git a/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/PermissionGrantingPathNode.scala b/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/PermissionGrantingPathNode.scala
index 3ddb9bc..aaaab91 100644
--- a/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/PermissionGrantingPathNode.scala
+++ b/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/PermissionGrantingPathNode.scala
@@ -8,10 +8,10 @@ class PermissionGrantingPathNode(wrapped: PathNode) extends PathNode {
 
   def doPrivileged[T](m: => T): T = {
      AccessController.doPrivileged(new PrivilegedAction[T] {
-		def run: T = {
-			m
-		}
-	})
+    def run: T = {
+      m
+    }
+  })
   }
   
   def exists(): Boolean = doPrivileged(wrapped.exists())

http://git-wip-us.apache.org/repos/asf/clerezza/blob/35448624/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/UnavailableSkeletonException.scala
----------------------------------------------------------------------
diff --git a/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/UnavailableSkeletonException.scala b/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/UnavailableSkeletonException.scala
index de8f696..5cb86e1 100644
--- a/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/UnavailableSkeletonException.scala
+++ b/bundledevtool/src/main/scala/org/apache/clerezza/bundledevtool/UnavailableSkeletonException.scala
@@ -20,6 +20,6 @@
 package org.apache.clerezza.bundledevtool
 
 class UnavailableSkeletonException(val requested: Symbol, val available: Seq[Symbol])
-	extends RuntimeException("The Skeleton "+requested.name+" is not avialble") {
+  extends RuntimeException("The Skeleton "+requested.name+" is not avialble") {
 
 }

http://git-wip-us.apache.org/repos/asf/clerezza/blob/35448624/bundledevtool/src/main/scala/sbt/ErrorHandling.scala
----------------------------------------------------------------------
diff --git a/bundledevtool/src/main/scala/sbt/ErrorHandling.scala b/bundledevtool/src/main/scala/sbt/ErrorHandling.scala
index d2566a1..ff31430 100644
--- a/bundledevtool/src/main/scala/sbt/ErrorHandling.scala
+++ b/bundledevtool/src/main/scala/sbt/ErrorHandling.scala
@@ -26,24 +26,24 @@ package sbt
 
 object ErrorHandling
 {
-	def translate[T](msg: => String)(f: => T) =
-		try { f }
-		catch { case e: Exception => throw new TranslatedException(msg + e.toString, e) }
+  def translate[T](msg: => String)(f: => T) =
+    try { f }
+    catch { case e: Exception => throw new TranslatedException(msg + e.toString, e) }
 
-	def wideConvert[T](f: => T): Either[Throwable, T] =
-		try { Right(f) }
-		catch
-		{
-			case ex @ (_: Exception | _: StackOverflowError) => Left(ex)
-			case err @ (_: ThreadDeath | _: VirtualMachineError) => throw err
-			case x => Left(x)
-		}
+  def wideConvert[T](f: => T): Either[Throwable, T] =
+    try { Right(f) }
+    catch
+    {
+      case ex @ (_: Exception | _: StackOverflowError) => Left(ex)
+      case err @ (_: ThreadDeath | _: VirtualMachineError) => throw err
+      case x => Left(x)
+    }
 
-	def convert[T](f: => T): Either[Exception, T] =
-		try { Right(f) }
-		catch { case e: Exception => Left(e) }
+  def convert[T](f: => T): Either[Exception, T] =
+    try { Right(f) }
+    catch { case e: Exception => Left(e) }
 }
 final class TranslatedException private[sbt](msg: String, cause: Throwable) extends RuntimeException(msg, cause)
 {
-	override def toString = msg
+  override def toString = msg
 }

http://git-wip-us.apache.org/repos/asf/clerezza/blob/35448624/bundledevtool/src/main/scala/sbt/io/Hash.scala
----------------------------------------------------------------------
diff --git a/bundledevtool/src/main/scala/sbt/io/Hash.scala b/bundledevtool/src/main/scala/sbt/io/Hash.scala
index 3f3bcf6..59aa5a3 100644
--- a/bundledevtool/src/main/scala/sbt/io/Hash.scala
+++ b/bundledevtool/src/main/scala/sbt/io/Hash.scala
@@ -28,70 +28,70 @@ import java.io.{ByteArrayInputStream, File, InputStream}
 
 object Hash
 {
-	private val BufferSize = 8192
-	def toHex(bytes: Array[Byte]): String =
-	{
-		val buffer = new StringBuilder(bytes.length * 2)
-		for(i <- 0 until bytes.length)
-		{
-			val b = bytes(i)
-			val bi: Int = if(b < 0) b + 256 else b
-			buffer append toHex((bi >>> 4).asInstanceOf[Byte])
-			buffer append toHex((bi & 0x0F).asInstanceOf[Byte])
-		}
-		buffer.toString
-	}
-	def fromHex(hex: String): Array[Byte] =
-	{
-		require((hex.length & 1) == 0, "Hex string must have length 2n.")
-		val array = new Array[Byte](hex.length >> 1)
-		for(i <- 0 until hex.length by 2)
-		{
-			val c1 = hex.charAt(i)
-			val c2 = hex.charAt(i+1)
-			array(i >> 1) = ((fromHex(c1) << 4) | fromHex(c2)).asInstanceOf[Byte]
-		}
-		array
-	}
-	/** Calculates the SHA-1 hash of the given String.*/
-	def apply(s: String): Array[Byte] = apply(new ByteArrayInputStream(s.getBytes("UTF-8")))
-	/** Calculates the SHA-1 hash of the given file.*/
-	def apply(file: File): Array[Byte] = Using.fileInputStream(file)(apply)
-	/** Calculates the SHA-1 hash of the given stream, closing it when finished.*/
-	def apply(stream: InputStream): Array[Byte] =
-	{
-		import java.security.{MessageDigest, DigestInputStream}
-		val digest = MessageDigest.getInstance("SHA")
-		try
-		{
-			val dis = new DigestInputStream(stream, digest)
-			val buffer = new Array[Byte](BufferSize)
-			while(dis.read(buffer) >= 0) {}
-			dis.close()
-			digest.digest
-		}
-		finally { stream.close() }
-	}
+  private val BufferSize = 8192
+  def toHex(bytes: Array[Byte]): String =
+  {
+    val buffer = new StringBuilder(bytes.length * 2)
+    for(i <- 0 until bytes.length)
+    {
+      val b = bytes(i)
+      val bi: Int = if(b < 0) b + 256 else b
+      buffer append toHex((bi >>> 4).asInstanceOf[Byte])
+      buffer append toHex((bi & 0x0F).asInstanceOf[Byte])
+    }
+    buffer.toString
+  }
+  def fromHex(hex: String): Array[Byte] =
+  {
+    require((hex.length & 1) == 0, "Hex string must have length 2n.")
+    val array = new Array[Byte](hex.length >> 1)
+    for(i <- 0 until hex.length by 2)
+    {
+      val c1 = hex.charAt(i)
+      val c2 = hex.charAt(i+1)
+      array(i >> 1) = ((fromHex(c1) << 4) | fromHex(c2)).asInstanceOf[Byte]
+    }
+    array
+  }
+  /** Calculates the SHA-1 hash of the given String.*/
+  def apply(s: String): Array[Byte] = apply(new ByteArrayInputStream(s.getBytes("UTF-8")))
+  /** Calculates the SHA-1 hash of the given file.*/
+  def apply(file: File): Array[Byte] = Using.fileInputStream(file)(apply)
+  /** Calculates the SHA-1 hash of the given stream, closing it when finished.*/
+  def apply(stream: InputStream): Array[Byte] =
+  {
+    import java.security.{MessageDigest, DigestInputStream}
+    val digest = MessageDigest.getInstance("SHA")
+    try
+    {
+      val dis = new DigestInputStream(stream, digest)
+      val buffer = new Array[Byte](BufferSize)
+      while(dis.read(buffer) >= 0) {}
+      dis.close()
+      digest.digest
+    }
+    finally { stream.close() }
+  }
 
-	private def toHex(b: Byte): Char =
-	{
-		require(b >= 0 && b <= 15, "Byte " + b + " was not between 0 and 15")
-		if(b < 10)
-			('0'.asInstanceOf[Int] + b).asInstanceOf[Char]
-		else
-			('a'.asInstanceOf[Int] + (b-10)).asInstanceOf[Char]
-	}
-	private def fromHex(c: Char): Int =
-	{
-		val b =
-			if(c >= '0' && c <= '9')
-				(c - '0')
-			else if(c >= 'a' && c <= 'f')
-				(c - 'a') + 10
-			else if(c >= 'A' && c <= 'F')
-				(c - 'A') + 10
-			else
-				throw new RuntimeException("Invalid hex character: '" + c + "'.")
-		b
-	}
+  private def toHex(b: Byte): Char =
+  {
+    require(b >= 0 && b <= 15, "Byte " + b + " was not between 0 and 15")
+    if(b < 10)
+      ('0'.asInstanceOf[Int] + b).asInstanceOf[Char]
+    else
+      ('a'.asInstanceOf[Int] + (b-10)).asInstanceOf[Char]
+  }
+  private def fromHex(c: Char): Int =
+  {
+    val b =
+      if(c >= '0' && c <= '9')
+        (c - '0')
+      else if(c >= 'a' && c <= 'f')
+        (c - 'a') + 10
+      else if(c >= 'A' && c <= 'F')
+        (c - 'A') + 10
+      else
+        throw new RuntimeException("Invalid hex character: '" + c + "'.")
+    b
+  }
 }

http://git-wip-us.apache.org/repos/asf/clerezza/blob/35448624/bundledevtool/src/main/scala/sbt/io/IO.scala
----------------------------------------------------------------------
diff --git a/bundledevtool/src/main/scala/sbt/io/IO.scala b/bundledevtool/src/main/scala/sbt/io/IO.scala
index a360338..f4d8d73 100644
--- a/bundledevtool/src/main/scala/sbt/io/IO.scala
+++ b/bundledevtool/src/main/scala/sbt/io/IO.scala
@@ -40,573 +40,573 @@ import Function.tupled
 
 object IO
 {
-	/** The maximum number of times a unique temporary filename is attempted to be created.*/
-	private val MaximumTries = 10
-	/** The producer of randomness for unique name generation.*/
-	private lazy val random = new java.util.Random
-	val temporaryDirectory = new File(System.getProperty("java.io.tmpdir"))
-	/** The size of the byte or char buffer used in various methods.*/
-	private val BufferSize = 8192
-	val Newline = System.getProperty("line.separator")
-
-	val utf8 = Charset.forName("UTF-8")
-
-	def classLocation(cl: Class[_]): URL =
-	{
-		val codeSource = cl.getProtectionDomain.getCodeSource
-		if(codeSource == null) error("No class location for " + cl)
-		else codeSource.getLocation
-	}
-	def classLocationFile(cl: Class[_]): File = toFile(classLocation(cl))
-	def classLocation[T](implicit mf: SManifest[T]): URL = classLocation(mf.erasure)
-	def classLocationFile[T](implicit mf: SManifest[T]): File = classLocationFile(mf.erasure)
-
-	def toFile(url: URL) =
-		try { new File(url.toURI) }
-		catch { case _: URISyntaxException => new File(url.getPath) }
-
-	/** Converts the given URL to a File.  If the URL is for an entry in a jar, the File for the jar is returned. */
-	def asFile(url: URL): File =
-	{
-		url.getProtocol match
-		{
-			case "file" => toFile(url)
-			case "jar" =>
-				val path = url.getPath
-				val end = path.indexOf('!')
-				new File(new URI(if(end == -1) path else path.substring(0, end)))
-			case _ => error("Invalid protocol " + url.getProtocol)
-		}
-	}
-	def assertDirectory(file: File) { assert(file.isDirectory, (if(file.exists) "Not a directory: " else "Directory not found: ") + file) }
-	def assertDirectories(file: File*) { file.foreach(assertDirectory) }
-
-	// "base.extension" -> (base, extension)
-	def split(name: String): (String, String) =
-	{
-		val lastDot = name.lastIndexOf('.')
-		if(lastDot >= 0)
-			(name.substring(0, lastDot), name.substring(lastDot+1))
-		else
-			(name, "")
-	}
-
-	def touch(files: Traversable[File]): Unit = files.foreach(touch)
-	/** Creates a file at the given location.*/
-	def touch(file: File)
-	{
-		createDirectory(file.getParentFile)
-		val created = translate("Could not create file " + file) { file.createNewFile() }
-		if(created || file.isDirectory)
-			()
-		else if(!file.setLastModified(System.currentTimeMillis))
-			error("Could not update last modified time for file " + file)
-	}
-	def createDirectories(dirs: Traversable[File]): Unit =
-		dirs.foreach(createDirectory)
-	def createDirectory(dir: File): Unit =
-	{
-		def failBase = "Could not create directory " + dir
-		if(dir.isDirectory || dir.mkdirs())
-			()
-		else if(dir.exists)
-			error(failBase + ": file exists and is not a directory.")
-		else
-			error(failBase)
-	}
-
-	/** Gzips the file 'in' and writes it to 'out'.  'in' cannot be the same file as 'out'. */
-	def gzip(in: File, out: File)
-	{
-		require(in != out, "Input file cannot be the same as the output file.")
-		Using.fileInputStream(in) { inputStream =>
-			Using.fileOutputStream()(out) { outputStream =>
-				gzip(inputStream, outputStream)
-			}
-		}
-	}
-	/** Gzips the InputStream 'in' and writes it to 'output'.  Neither stream is closed.*/
-	def gzip(input: InputStream, output: OutputStream): Unit =
-		gzipOutputStream(output) { gzStream => transfer(input, gzStream) }
-
-	/** Gunzips the file 'in' and writes it to 'out'.  'in' cannot be the same file as 'out'. */
-	def gunzip(in: File, out: File)
-	{
-		require(in != out, "Input file cannot be the same as the output file.")
-		Using.fileInputStream(in) { inputStream =>
-			Using.fileOutputStream()(out) { outputStream =>
-				gunzip(inputStream, outputStream)
-			}
-		}
-	}
-	/** Gunzips the InputStream 'input' and writes it to 'output'.  Neither stream is closed.*/
-	def gunzip(input: InputStream, output: OutputStream): Unit =
-		gzipInputStream(input) { gzStream => transfer(gzStream, output) }
-
-	def unzip(from: File, toDirectory: File, filter: NameFilter = AllPassFilter): Set[File] = fileInputStream(from)(in => unzipStream(in, toDirectory, filter))
-	def unzipURL(from: URL, toDirectory: File, filter: NameFilter = AllPassFilter): Set[File] = urlInputStream(from)(in => unzipStream(in, toDirectory, filter))
-	def unzipStream(from: InputStream, toDirectory: File, filter: NameFilter = AllPassFilter): Set[File] =
-	{
-		createDirectory(toDirectory)
-		zipInputStream(from) { zipInput => extract(zipInput, toDirectory, filter) }
-	}
-	private def extract(from: ZipInputStream, toDirectory: File, filter: NameFilter) =
-	{
-		val set = new HashSet[File]
-		def next()
-		{
-			val entry = from.getNextEntry
-			if(entry == null)
-				()
-			else
-			{
-				val name = entry.getName
-				if(filter.accept(name))
-				{
-					val target = new File(toDirectory, name)
-					//log.debug("Extracting zip entry '" + name + "' to '" + target + "'")
-					if(entry.isDirectory)
-						createDirectory(target)
-					else
-					{
-						set += target
-						translate("Error extracting zip entry '" + name + "' to '" + target + "': ") {
-							fileOutputStream(false)(target) { out => transfer(from, out) }
-						}
-					}
-					//target.setLastModified(entry.getTime)
-				}
-				else
-				{
-					//log.debug("Ignoring zip entry '" + name + "'")
-				}
-				from.closeEntry()
-				next()
-			}
-		}
-		next()
-		Set() ++ set
-	}
-
-	/** Retrieves the content of the given URL and writes it to the given File. */
-	def download(url: URL, to: File) =
-		Using.urlInputStream(url) { inputStream =>
-			transfer(inputStream, to)
-		}
-
-	def transfer(in: File, out: File): Unit =
-		fileInputStream(in){ in => transfer(in, out) }
-
-	def transfer(in: File, out: OutputStream): Unit =
-		fileInputStream(in){ in => transfer(in, out) }
-
-	/** Copies all bytes from the given input stream to the given File.*/
-	def transfer(in: InputStream, to: File): Unit =
-		Using.fileOutputStream()(to) { outputStream =>
-			transfer(in, outputStream)
-		}
-
-	/** Copies all bytes from the given input stream to the given output stream.
-	* Neither stream is closed.*/
-	def transfer(in: InputStream, out: OutputStream): Unit = transferImpl(in, out, false)
-	/** Copies all bytes from the given input stream to the given output stream.  The
-	* input stream is closed after the method completes.*/
-	def transferAndClose(in: InputStream, out: OutputStream): Unit = transferImpl(in, out, true)
-	private def transferImpl(in: InputStream, out: OutputStream, close: Boolean)
-	{
-		try
-		{
-			val buffer = new Array[Byte](BufferSize)
-			def read()
-			{
-				val byteCount = in.read(buffer)
-				if(byteCount >= 0)
-				{
-					out.write(buffer, 0, byteCount)
-					read()
-				}
-			}
-			read()
-		}
-		finally { if(close) in.close }
-	}
-
-	/** Creates a temporary directory and provides its location to the given function.  The directory
-	* is deleted after the function returns.*/
-	def withTemporaryDirectory[T](action: File => T): T =
-	{
-		val dir = createTemporaryDirectory
-		try { action(dir) }
-		finally { delete(dir) }
-	}
-	def createTemporaryDirectory: File =
-	{
-		def create(tries: Int): File =
-		{
-			if(tries > MaximumTries)
-				error("Could not create temporary directory.")
-			else
-			{
-				val randomName = "sbt_" + java.lang.Integer.toHexString(random.nextInt)
-				val f = new File(temporaryDirectory, randomName)
-
-				try { createDirectory(f); f }
-				catch { case e: Exception => create(tries + 1) }
-			}
-		}
-		create(0)
-	}
-	def withTemporaryFile[T](prefix: String, postfix: String)(action: File => T): T =
-	{
-		val file = File.createTempFile(prefix, postfix)
-		try { action(file) }
-		finally { file.delete() }
-	}
-
-	private[sbt] def jars(dir: File): Iterable[File] = listFiles(dir, GlobFilter("*.jar"))
-
-	def deleteIfEmpty(dirs: collection.Set[File]): Unit =
-	{
-		val isEmpty = new HashMap[File, Boolean]
-		def visit(f: File): Boolean = isEmpty.getOrElseUpdate(f, dirs(f) && f.isDirectory && (f.listFiles forall visit) )
-
-		dirs foreach visit
-		for( (f, true) <- isEmpty) f.delete
-	}
-
-	def delete(files: Iterable[File]): Unit = files.foreach(delete)
-	def delete(file: File)
-	{
-		translate("Error deleting file " + file + ": ")
-		{
-			if(file.isDirectory)
-			{
-				delete(listFiles(file))
-				file.delete
-			}
-			else if(file.exists)
-				file.delete
-		}
-	}
-	def listFiles(filter: java.io.FileFilter)(dir: File): Array[File] = wrapNull(dir.listFiles(filter))
-	def listFiles(dir: File, filter: java.io.FileFilter): Array[File] = wrapNull(dir.listFiles(filter))
-	def listFiles(dir: File): Array[File] = wrapNull(dir.listFiles())
-	private[sbt] def wrapNull(a: Array[File]) =
-	{
-		if(a == null)
-			new Array[File](0)
-		else
-			a
-	}
-
-
-	/** Creates a jar file.
-	* @param sources The files to include in the jar file paired with the entry name in the jar.
-	* @param outputJar The file to write the jar to.
-	* @param manifest The manifest for the jar.*/
-	def jar(sources: Traversable[(File,String)], outputJar: File, manifest: Manifest): Unit =
-		archive(sources.toSeq, outputJar, Some(manifest))
-	/** Creates a zip file.
-	* @param sources The files to include in the zip file paired with the entry name in the zip.
-	* @param outputZip The file to write the zip to.*/
-	def zip(sources: Traversable[(File,String)], outputZip: File): Unit =
-		archive(sources.toSeq, outputZip, None)
-
-	private def archive(sources: Seq[(File,String)], outputFile: File, manifest: Option[Manifest])
-	{
-		if(outputFile.isDirectory)
-			error("Specified output file " + outputFile + " is a directory.")
-		else
-		{
-			val outputDir = outputFile.getParentFile
-			createDirectory(outputDir)
-			withZipOutput(outputFile, manifest)
-			{ output =>
-				val createEntry: (String => ZipEntry) = if(manifest.isDefined) new JarEntry(_) else new ZipEntry(_)
-				writeZip(sources, output)(createEntry)
-			}
-		}
-	}
-	private def writeZip(sources: Seq[(File,String)], output: ZipOutputStream)(createEntry: String => ZipEntry)
-	{
-			import Path.{lazyPathFinder => pf}
-		val files = sources.collect { case (file,name) if file.isFile => (file, normalizeName(name)) }
-		val now = System.currentTimeMillis
-		// The CRC32 for an empty value, needed to store directories in zip files
-		val emptyCRC = new CRC32().getValue()
-
-		def addDirectoryEntry(name: String)
-		{
-			output putNextEntry makeDirectoryEntry(name)
-			output.closeEntry()
-		}
-
-		def makeDirectoryEntry(name: String) =
-		{
-//			log.debug("\tAdding directory " + relativePath + " ...")
-			val e = createEntry(name)
-			e setTime now
-			e setSize 0
-			e setMethod ZipEntry.STORED
-			e setCrc emptyCRC
-			e
-		}
-
-		def makeFileEntry(file: File, name: String) =
-		{
-//			log.debug("\tAdding " + file + " as " + name + " ...")
-			val e = createEntry(name)
-			e setTime file.lastModified
-			e
-		}
-		def addFileEntry(file: File, name: String)
-		{
-			output putNextEntry makeFileEntry(file, name)
-			transfer(file, output)
-			output.closeEntry()
-		}
-
-		//Calculate directories and add them to the generated Zip
-		allDirectoryPaths(files) foreach addDirectoryEntry
-
-		//Add all files to the generated Zip
-		files foreach { case (file, name) => addFileEntry(file, name) }
-	}
-
-	// map a path a/b/c to List("a", "b")
-	private def relativeComponents(path: String): List[String] =
-		path.split("/").toList.dropRight(1)
-
-	// map components List("a", "b", "c") to List("a/b/c/", "a/b/", "a/", "")
-	private def directories(path: List[String]): List[String] =
-		path.foldLeft(List(""))( (e,l) => (e.head + l + "/") :: e )
-
-	// map a path a/b/c to List("a/b/", "a/")
-	private def directoryPaths(path: String): List[String] =
-		directories(relativeComponents(path)).filter(_.length > 1)
-
-	// produce a sorted list of all the subdirectories of all provided files
-	private def allDirectoryPaths(files: Iterable[(File,String)]) =
-		TreeSet[String]() ++ (files flatMap { case (file, name) => directoryPaths(name) })
-
-	private def normalizeDirName(name: String) =
-	{
-		val norm1 = normalizeName(name)
-		if(norm1.endsWith("/")) norm1 else (norm1 + "/")
-	}
-	private def normalizeName(name: String) =
-	{
-		val sep = File.separatorChar
-		if(sep == '/') name else name.replace(sep, '/')
-	}
-
-	private def withZipOutput(file: File, manifest: Option[Manifest])(f: ZipOutputStream => Unit)
-	{
-		fileOutputStream(false)(file) { fileOut =>
-			val (zipOut, ext) =
-				manifest match
-				{
-					case Some(mf) =>
-					{
-						import Attributes.Name.MANIFEST_VERSION
-						val main = mf.getMainAttributes
-						if(!main.containsKey(MANIFEST_VERSION))
-							main.put(MANIFEST_VERSION, "1.0")
-						(new JarOutputStream(fileOut, mf), "jar")
-					}
-					case None => (new ZipOutputStream(fileOut), "zip")
-				}
-			try { f(zipOut) }
-			catch { case e: Exception => "Error writing " + ext + ": " + e.toString }
-			finally { zipOut.close }
-		}
-	}
-	def relativize(base: File, file: File): Option[String] =
-	{
-		val pathString = file.getAbsolutePath
-		baseFileString(base) flatMap
-		{
-			baseString =>
-			{
-				if(pathString.startsWith(baseString))
-					Some(pathString.substring(baseString.length))
-				else
-					None
-			}
-		}
-	}
-	private def baseFileString(baseFile: File): Option[String] =
-	{
-		if(baseFile.isDirectory)
-		{
-			val cp = baseFile.getAbsolutePath
-			assert(cp.length > 0)
-			val normalized = if(cp.charAt(cp.length - 1) == File.separatorChar) cp else cp + File.separatorChar
-			Some(normalized)
-		}
-		else
-			None
-	}
-	def copy(sources: Traversable[(File,File)], overwrite: Boolean = false, preserveLastModified: Boolean = false): Set[File] =
-		sources.map( tupled(copyImpl(overwrite, preserveLastModified)) ).toSet
-	private def copyImpl(overwrite: Boolean, preserveLastModified: Boolean)(from: File, to: File): File =
-	{
-		if(overwrite || !to.exists || from.lastModified > to.lastModified)
-		{
-			if(from.isDirectory)
-				createDirectory(to)
-			else
-			{
-				createDirectory(to.getParentFile)
-				copyFile(from, to, preserveLastModified)
-			}
-		}
-		to
-	}
-	def copyDirectory(source: File, target: File, overwrite: Boolean = false, preserveLastModified: Boolean = false): Unit =
-		copy( (Path.fromFile(source) ***) x Path.rebase(source, target), overwrite, preserveLastModified)
-
-	def copyFile(sourceFile: File, targetFile: File, preserveLastModified: Boolean = false)
-	{
-		require(sourceFile.exists, "Source file '" + sourceFile.getAbsolutePath + "' does not exist.")
-		require(!sourceFile.isDirectory, "Source file '" + sourceFile.getAbsolutePath + "' is a directory.")
-		fileInputChannel(sourceFile) { in =>
-			fileOutputChannel(targetFile) { out =>
-				val copied = out.transferFrom(in, 0, in.size)
-				if(copied != in.size)
-					error("Could not copy '" + sourceFile + "' to '" + targetFile + "' (" + copied + "/" + in.size + " bytes copied)")
-			}
-		}
-		if(preserveLastModified)
-			copyLastModified(sourceFile, targetFile)
-	}
-	def copyLastModified(sourceFile: File, targetFile: File) = targetFile.setLastModified( sourceFile.lastModified )
-	def defaultCharset = utf8
-
-	def write(file: File, content: String, charset: Charset = defaultCharset, append: Boolean = false): Unit =
-		writer(file, content, charset, append) { _.write(content)  }
-
-	def writer[T](file: File, content: String, charset: Charset, append: Boolean = false)(f: BufferedWriter => T): T =
-	{
-		if(charset.newEncoder.canEncode(content))
-			fileWriter(charset, append)(file) { f }
-		else
-			error("String cannot be encoded by charset " + charset.name)
-	}
-
-	def reader[T](file: File, charset: Charset = defaultCharset)(f: BufferedReader => T): T =
-		fileReader(charset)(file) { f }
-
-	def read(file: File, charset: Charset = defaultCharset): String =
-	{
-		val out = new ByteArrayOutputStream(file.length.toInt)
-		transfer(file, out)
-		out.toString(charset.name)
-	}
-	/** doesn't close the InputStream */
-	def readStream(in: InputStream, charset: Charset = defaultCharset): String =
-	{
-		val out = new ByteArrayOutputStream
-		transfer(in, out)
-		out.toString(charset.name)
-	}
-	def readBytes(file: File): Array[Byte] = fileInputStream(file)(readBytes)
-	/** doesn't close the InputStream */
-	def readBytes(in: InputStream): Array[Byte] =
-	{
-		val out = new ByteArrayOutputStream
-		transfer(in, out)
-		out.toByteArray
-	}
-
-	def append(file: File, content: String, charset: Charset = defaultCharset): Unit =
-		write(file, content, charset, true)
-	def append(file: File, bytes: Array[Byte]): Unit =
-		writeBytes(file, bytes, true)
-
-	def write(file: File, bytes: Array[Byte]): Unit =
-		writeBytes(file, bytes, false)
-	private def writeBytes(file: File, bytes: Array[Byte], append: Boolean): Unit =
-		fileOutputStream(append)(file) { _.write(bytes) }
-
-
-	// Not optimized for large files
-	def readLines(file: File, charset: Charset = defaultCharset): List[String] =
-		fileReader(charset)(file)(readLines)
-		
-	// Not optimized for large files
-	def readLines(in: BufferedReader): List[String] = 
-		foldLines[List[String]](in, Nil)( (accum, line) => line :: accum ).reverse
-	
-	def foreachLine(in: BufferedReader)(f: String => Unit): Unit =
-		foldLines(in, ())( (_, line) => f(line) )
-		
-	def foldLines[T](in: BufferedReader, init: T)(f: (T, String) => T): T =
-	{
-		def readLine(accum: T): T =
-		{
-			val line = in.readLine()
-			if(line eq null) accum else readLine(f(accum, line))
-		}
-		readLine(init)
-	}
-	
-	def writeLines(file: File, lines: Seq[String], charset: Charset = defaultCharset, append: Boolean = false): Unit =
-		writer(file, lines.headOption.getOrElse(""), charset, append) { w =>
-			lines.foreach { line => w.write(line); w.newLine() }
-		}
-		
-	def write(properties: Properties, label: String, to: File) =
-		fileOutputStream()(to) { output => properties.store(output, label) }
-	def load(properties: Properties, from: File): Unit =
-		if(from.exists)
-			fileInputStream(from){ input => properties.load(input) }
-
-	/** A pattern used to split a String by path separator characters.*/
-	private val PathSeparatorPattern = java.util.regex.Pattern.compile(File.pathSeparator)
-
-	/** Splits a String around path separator characters. */
-	def pathSplit(s: String) = PathSeparatorPattern.split(s)
-
-	/** Move the provided files to a temporary location.
-	*   If 'f' returns normally, delete the files.
-	*   If 'f' throws an Exception, return the files to their original location.*/
-	def stash[T](files: Set[File])(f: => T): T =
-		withTemporaryDirectory { dir =>
-			val stashed = stashLocations(dir, files.toArray)
-			move(stashed)
-
-			try { f } catch { case e: Exception =>
-				try { move(stashed.map(_.swap)); throw e }
-				catch { case _: Exception => throw e }
-			}
-		}
-
-	private def stashLocations(dir: File, files: Array[File]) =
-		for( (file, index) <- files.zipWithIndex) yield
-			(file, new File(dir, index.toHexString))
-
-	def move(files: Traversable[(File, File)]): Unit =
-		files.foreach(Function.tupled(move))
-		
-	def move(a: File, b: File): Unit =
-	{
-		if(b.exists)
-			delete(b)
-		if(!a.renameTo(b))
-		{
-			copyFile(a, b, true)
-			delete(a)
-		}
-	}
-
-	def gzipFileOut[T](file: File)(f: OutputStream => T): T =
-		Using.fileOutputStream()(file) { fout =>
-		Using.gzipOutputStream(fout) { outg =>
-		Using.bufferedOutputStream(outg)(f) }}
-
-	def gzipFileIn[T](file: File)(f: InputStream => T): T =
-		Using.fileInputStream(file) { fin =>
-		Using.gzipInputStream(fin) { ing =>
-		Using.bufferedInputStream(ing)(f) }}
+  /** The maximum number of times a unique temporary filename is attempted to be created.*/
+  private val MaximumTries = 10
+  /** The producer of randomness for unique name generation.*/
+  private lazy val random = new java.util.Random
+  val temporaryDirectory = new File(System.getProperty("java.io.tmpdir"))
+  /** The size of the byte or char buffer used in various methods.*/
+  private val BufferSize = 8192
+  val Newline = System.getProperty("line.separator")
+
+  val utf8 = Charset.forName("UTF-8")
+
+  def classLocation(cl: Class[_]): URL =
+  {
+    val codeSource = cl.getProtectionDomain.getCodeSource
+    if(codeSource == null) error("No class location for " + cl)
+    else codeSource.getLocation
+  }
+  def classLocationFile(cl: Class[_]): File = toFile(classLocation(cl))
+  def classLocation[T](implicit mf: SManifest[T]): URL = classLocation(mf.erasure)
+  def classLocationFile[T](implicit mf: SManifest[T]): File = classLocationFile(mf.erasure)
+
+  def toFile(url: URL) =
+    try { new File(url.toURI) }
+    catch { case _: URISyntaxException => new File(url.getPath) }
+
+  /** Converts the given URL to a File.  If the URL is for an entry in a jar, the File for the jar is returned. */
+  def asFile(url: URL): File =
+  {
+    url.getProtocol match
+    {
+      case "file" => toFile(url)
+      case "jar" =>
+        val path = url.getPath
+        val end = path.indexOf('!')
+        new File(new URI(if(end == -1) path else path.substring(0, end)))
+      case _ => error("Invalid protocol " + url.getProtocol)
+    }
+  }
+  def assertDirectory(file: File) { assert(file.isDirectory, (if(file.exists) "Not a directory: " else "Directory not found: ") + file) }
+  def assertDirectories(file: File*) { file.foreach(assertDirectory) }
+
+  // "base.extension" -> (base, extension)
+  def split(name: String): (String, String) =
+  {
+    val lastDot = name.lastIndexOf('.')
+    if(lastDot >= 0)
+      (name.substring(0, lastDot), name.substring(lastDot+1))
+    else
+      (name, "")
+  }
+
+  def touch(files: Traversable[File]): Unit = files.foreach(touch)
+  /** Creates a file at the given location.*/
+  def touch(file: File)
+  {
+    createDirectory(file.getParentFile)
+    val created = translate("Could not create file " + file) { file.createNewFile() }
+    if(created || file.isDirectory)
+      ()
+    else if(!file.setLastModified(System.currentTimeMillis))
+      error("Could not update last modified time for file " + file)
+  }
+  def createDirectories(dirs: Traversable[File]): Unit =
+    dirs.foreach(createDirectory)
+  def createDirectory(dir: File): Unit =
+  {
+    def failBase = "Could not create directory " + dir
+    if(dir.isDirectory || dir.mkdirs())
+      ()
+    else if(dir.exists)
+      error(failBase + ": file exists and is not a directory.")
+    else
+      error(failBase)
+  }
+
+  /** Gzips the file 'in' and writes it to 'out'.  'in' cannot be the same file as 'out'. */
+  def gzip(in: File, out: File)
+  {
+    require(in != out, "Input file cannot be the same as the output file.")
+    Using.fileInputStream(in) { inputStream =>
+      Using.fileOutputStream()(out) { outputStream =>
+        gzip(inputStream, outputStream)
+      }
+    }
+  }
+  /** Gzips the InputStream 'in' and writes it to 'output'.  Neither stream is closed.*/
+  def gzip(input: InputStream, output: OutputStream): Unit =
+    gzipOutputStream(output) { gzStream => transfer(input, gzStream) }
+
+  /** Gunzips the file 'in' and writes it to 'out'.  'in' cannot be the same file as 'out'. */
+  def gunzip(in: File, out: File)
+  {
+    require(in != out, "Input file cannot be the same as the output file.")
+    Using.fileInputStream(in) { inputStream =>
+      Using.fileOutputStream()(out) { outputStream =>
+        gunzip(inputStream, outputStream)
+      }
+    }
+  }
+  /** Gunzips the InputStream 'input' and writes it to 'output'.  Neither stream is closed.*/
+  def gunzip(input: InputStream, output: OutputStream): Unit =
+    gzipInputStream(input) { gzStream => transfer(gzStream, output) }
+
+  def unzip(from: File, toDirectory: File, filter: NameFilter = AllPassFilter): Set[File] = fileInputStream(from)(in => unzipStream(in, toDirectory, filter))
+  def unzipURL(from: URL, toDirectory: File, filter: NameFilter = AllPassFilter): Set[File] = urlInputStream(from)(in => unzipStream(in, toDirectory, filter))
+  def unzipStream(from: InputStream, toDirectory: File, filter: NameFilter = AllPassFilter): Set[File] =
+  {
+    createDirectory(toDirectory)
+    zipInputStream(from) { zipInput => extract(zipInput, toDirectory, filter) }
+  }
+  private def extract(from: ZipInputStream, toDirectory: File, filter: NameFilter) =
+  {
+    val set = new HashSet[File]
+    def next()
+    {
+      val entry = from.getNextEntry
+      if(entry == null)
+        ()
+      else
+      {
+        val name = entry.getName
+        if(filter.accept(name))
+        {
+          val target = new File(toDirectory, name)
+          //log.debug("Extracting zip entry '" + name + "' to '" + target + "'")
+          if(entry.isDirectory)
+            createDirectory(target)
+          else
+          {
+            set += target
+            translate("Error extracting zip entry '" + name + "' to '" + target + "': ") {
+              fileOutputStream(false)(target) { out => transfer(from, out) }
+            }
+          }
+          //target.setLastModified(entry.getTime)
+        }
+        else
+        {
+          //log.debug("Ignoring zip entry '" + name + "'")
+        }
+        from.closeEntry()
+        next()
+      }
+    }
+    next()
+    Set() ++ set
+  }
+
+  /** Retrieves the content of the given URL and writes it to the given File. */
+  def download(url: URL, to: File) =
+    Using.urlInputStream(url) { inputStream =>
+      transfer(inputStream, to)
+    }
+
+  def transfer(in: File, out: File): Unit =
+    fileInputStream(in){ in => transfer(in, out) }
+
+  def transfer(in: File, out: OutputStream): Unit =
+    fileInputStream(in){ in => transfer(in, out) }
+
+  /** Copies all bytes from the given input stream to the given File.*/
+  def transfer(in: InputStream, to: File): Unit =
+    Using.fileOutputStream()(to) { outputStream =>
+      transfer(in, outputStream)
+    }
+
+  /** Copies all bytes from the given input stream to the given output stream.
+  * Neither stream is closed.*/
+  def transfer(in: InputStream, out: OutputStream): Unit = transferImpl(in, out, false)
+  /** Copies all bytes from the given input stream to the given output stream.  The
+  * input stream is closed after the method completes.*/
+  def transferAndClose(in: InputStream, out: OutputStream): Unit = transferImpl(in, out, true)
+  private def transferImpl(in: InputStream, out: OutputStream, close: Boolean)
+  {
+    try
+    {
+      val buffer = new Array[Byte](BufferSize)
+      def read()
+      {
+        val byteCount = in.read(buffer)
+        if(byteCount >= 0)
+        {
+          out.write(buffer, 0, byteCount)
+          read()
+        }
+      }
+      read()
+    }
+    finally { if(close) in.close }
+  }
+
+  /** Creates a temporary directory and provides its location to the given function.  The directory
+  * is deleted after the function returns.*/
+  def withTemporaryDirectory[T](action: File => T): T =
+  {
+    val dir = createTemporaryDirectory
+    try { action(dir) }
+    finally { delete(dir) }
+  }
+  def createTemporaryDirectory: File =
+  {
+    def create(tries: Int): File =
+    {
+      if(tries > MaximumTries)
+        error("Could not create temporary directory.")
+      else
+      {
+        val randomName = "sbt_" + java.lang.Integer.toHexString(random.nextInt)
+        val f = new File(temporaryDirectory, randomName)
+
+        try { createDirectory(f); f }
+        catch { case e: Exception => create(tries + 1) }
+      }
+    }
+    create(0)
+  }
+  def withTemporaryFile[T](prefix: String, postfix: String)(action: File => T): T =
+  {
+    val file = File.createTempFile(prefix, postfix)
+    try { action(file) }
+    finally { file.delete() }
+  }
+
+  private[sbt] def jars(dir: File): Iterable[File] = listFiles(dir, GlobFilter("*.jar"))
+
+  def deleteIfEmpty(dirs: collection.Set[File]): Unit =
+  {
+    val isEmpty = new HashMap[File, Boolean]
+    def visit(f: File): Boolean = isEmpty.getOrElseUpdate(f, dirs(f) && f.isDirectory && (f.listFiles forall visit) )
+
+    dirs foreach visit
+    for( (f, true) <- isEmpty) f.delete
+  }
+
+  def delete(files: Iterable[File]): Unit = files.foreach(delete)
+  def delete(file: File)
+  {
+    translate("Error deleting file " + file + ": ")
+    {
+      if(file.isDirectory)
+      {
+        delete(listFiles(file))
+        file.delete
+      }
+      else if(file.exists)
+        file.delete
+    }
+  }
+  def listFiles(filter: java.io.FileFilter)(dir: File): Array[File] = wrapNull(dir.listFiles(filter))
+  def listFiles(dir: File, filter: java.io.FileFilter): Array[File] = wrapNull(dir.listFiles(filter))
+  def listFiles(dir: File): Array[File] = wrapNull(dir.listFiles())
+  private[sbt] def wrapNull(a: Array[File]) =
+  {
+    if(a == null)
+      new Array[File](0)
+    else
+      a
+  }
+
+
+  /** Creates a jar file.
+  * @param sources The files to include in the jar file paired with the entry name in the jar.
+  * @param outputJar The file to write the jar to.
+  * @param manifest The manifest for the jar.*/
+  def jar(sources: Traversable[(File,String)], outputJar: File, manifest: Manifest): Unit =
+    archive(sources.toSeq, outputJar, Some(manifest))
+  /** Creates a zip file.
+  * @param sources The files to include in the zip file paired with the entry name in the zip.
+  * @param outputZip The file to write the zip to.*/
+  def zip(sources: Traversable[(File,String)], outputZip: File): Unit =
+    archive(sources.toSeq, outputZip, None)
+
+  private def archive(sources: Seq[(File,String)], outputFile: File, manifest: Option[Manifest])
+  {
+    if(outputFile.isDirectory)
+      error("Specified output file " + outputFile + " is a directory.")
+    else
+    {
+      val outputDir = outputFile.getParentFile
+      createDirectory(outputDir)
+      withZipOutput(outputFile, manifest)
+      { output =>
+        val createEntry: (String => ZipEntry) = if(manifest.isDefined) new JarEntry(_) else new ZipEntry(_)
+        writeZip(sources, output)(createEntry)
+      }
+    }
+  }
+  private def writeZip(sources: Seq[(File,String)], output: ZipOutputStream)(createEntry: String => ZipEntry)
+  {
+      import Path.{lazyPathFinder => pf}
+    val files = sources.collect { case (file,name) if file.isFile => (file, normalizeName(name)) }
+    val now = System.currentTimeMillis
+    // The CRC32 for an empty value, needed to store directories in zip files
+    val emptyCRC = new CRC32().getValue()
+
+    def addDirectoryEntry(name: String)
+    {
+      output putNextEntry makeDirectoryEntry(name)
+      output.closeEntry()
+    }
+
+    def makeDirectoryEntry(name: String) =
+    {
+//      log.debug("\tAdding directory " + relativePath + " ...")
+      val e = createEntry(name)
+      e setTime now
+      e setSize 0
+      e setMethod ZipEntry.STORED
+      e setCrc emptyCRC
+      e
+    }
+
+    def makeFileEntry(file: File, name: String) =
+    {
+//      log.debug("\tAdding " + file + " as " + name + " ...")
+      val e = createEntry(name)
+      e setTime file.lastModified
+      e
+    }
+    def addFileEntry(file: File, name: String)
+    {
+      output putNextEntry makeFileEntry(file, name)
+      transfer(file, output)
+      output.closeEntry()
+    }
+
+    //Calculate directories and add them to the generated Zip
+    allDirectoryPaths(files) foreach addDirectoryEntry
+
+    //Add all files to the generated Zip
+    files foreach { case (file, name) => addFileEntry(file, name) }
+  }
+
+  // map a path a/b/c to List("a", "b")
+  private def relativeComponents(path: String): List[String] =
+    path.split("/").toList.dropRight(1)
+
+  // map components List("a", "b", "c") to List("a/b/c/", "a/b/", "a/", "")
+  private def directories(path: List[String]): List[String] =
+    path.foldLeft(List(""))( (e,l) => (e.head + l + "/") :: e )
+
+  // map a path a/b/c to List("a/b/", "a/")
+  private def directoryPaths(path: String): List[String] =
+    directories(relativeComponents(path)).filter(_.length > 1)
+
+  // produce a sorted list of all the subdirectories of all provided files
+  private def allDirectoryPaths(files: Iterable[(File,String)]) =
+    TreeSet[String]() ++ (files flatMap { case (file, name) => directoryPaths(name) })
+
+  private def normalizeDirName(name: String) =
+  {
+    val norm1 = normalizeName(name)
+    if(norm1.endsWith("/")) norm1 else (norm1 + "/")
+  }
+  private def normalizeName(name: String) =
+  {
+    val sep = File.separatorChar
+    if(sep == '/') name else name.replace(sep, '/')
+  }
+
+  private def withZipOutput(file: File, manifest: Option[Manifest])(f: ZipOutputStream => Unit)
+  {
+    fileOutputStream(false)(file) { fileOut =>
+      val (zipOut, ext) =
+        manifest match
+        {
+          case Some(mf) =>
+          {
+            import Attributes.Name.MANIFEST_VERSION
+            val main = mf.getMainAttributes
+            if(!main.containsKey(MANIFEST_VERSION))
+              main.put(MANIFEST_VERSION, "1.0")
+            (new JarOutputStream(fileOut, mf), "jar")
+          }
+          case None => (new ZipOutputStream(fileOut), "zip")
+        }
+      try { f(zipOut) }
+      catch { case e: Exception => "Error writing " + ext + ": " + e.toString }
+      finally { zipOut.close }
+    }
+  }
+  def relativize(base: File, file: File): Option[String] =
+  {
+    val pathString = file.getAbsolutePath
+    baseFileString(base) flatMap
+    {
+      baseString =>
+      {
+        if(pathString.startsWith(baseString))
+          Some(pathString.substring(baseString.length))
+        else
+          None
+      }
+    }
+  }
+  private def baseFileString(baseFile: File): Option[String] =
+  {
+    if(baseFile.isDirectory)
+    {
+      val cp = baseFile.getAbsolutePath
+      assert(cp.length > 0)
+      val normalized = if(cp.charAt(cp.length - 1) == File.separatorChar) cp else cp + File.separatorChar
+      Some(normalized)
+    }
+    else
+      None
+  }
+  def copy(sources: Traversable[(File,File)], overwrite: Boolean = false, preserveLastModified: Boolean = false): Set[File] =
+    sources.map( tupled(copyImpl(overwrite, preserveLastModified)) ).toSet
+  private def copyImpl(overwrite: Boolean, preserveLastModified: Boolean)(from: File, to: File): File =
+  {
+    if(overwrite || !to.exists || from.lastModified > to.lastModified)
+    {
+      if(from.isDirectory)
+        createDirectory(to)
+      else
+      {
+        createDirectory(to.getParentFile)
+        copyFile(from, to, preserveLastModified)
+      }
+    }
+    to
+  }
+  def copyDirectory(source: File, target: File, overwrite: Boolean = false, preserveLastModified: Boolean = false): Unit =
+    copy( (Path.fromFile(source) ***) x Path.rebase(source, target), overwrite, preserveLastModified)
+
+  def copyFile(sourceFile: File, targetFile: File, preserveLastModified: Boolean = false)
+  {
+    require(sourceFile.exists, "Source file '" + sourceFile.getAbsolutePath + "' does not exist.")
+    require(!sourceFile.isDirectory, "Source file '" + sourceFile.getAbsolutePath + "' is a directory.")
+    fileInputChannel(sourceFile) { in =>
+      fileOutputChannel(targetFile) { out =>
+        val copied = out.transferFrom(in, 0, in.size)
+        if(copied != in.size)
+          error("Could not copy '" + sourceFile + "' to '" + targetFile + "' (" + copied + "/" + in.size + " bytes copied)")
+      }
+    }
+    if(preserveLastModified)
+      copyLastModified(sourceFile, targetFile)
+  }
+  def copyLastModified(sourceFile: File, targetFile: File) = targetFile.setLastModified( sourceFile.lastModified )
+  def defaultCharset = utf8
+
+  def write(file: File, content: String, charset: Charset = defaultCharset, append: Boolean = false): Unit =
+    writer(file, content, charset, append) { _.write(content)  }
+
+  def writer[T](file: File, content: String, charset: Charset, append: Boolean = false)(f: BufferedWriter => T): T =
+  {
+    if(charset.newEncoder.canEncode(content))
+      fileWriter(charset, append)(file) { f }
+    else
+      error("String cannot be encoded by charset " + charset.name)
+  }
+
+  def reader[T](file: File, charset: Charset = defaultCharset)(f: BufferedReader => T): T =
+    fileReader(charset)(file) { f }
+
+  def read(file: File, charset: Charset = defaultCharset): String =
+  {
+    val out = new ByteArrayOutputStream(file.length.toInt)
+    transfer(file, out)
+    out.toString(charset.name)
+  }
+  /** doesn't close the InputStream */
+  def readStream(in: InputStream, charset: Charset = defaultCharset): String =
+  {
+    val out = new ByteArrayOutputStream
+    transfer(in, out)
+    out.toString(charset.name)
+  }
+  def readBytes(file: File): Array[Byte] = fileInputStream(file)(readBytes)
+  /** doesn't close the InputStream */
+  def readBytes(in: InputStream): Array[Byte] =
+  {
+    val out = new ByteArrayOutputStream
+    transfer(in, out)
+    out.toByteArray
+  }
+
+  def append(file: File, content: String, charset: Charset = defaultCharset): Unit =
+    write(file, content, charset, true)
+  def append(file: File, bytes: Array[Byte]): Unit =
+    writeBytes(file, bytes, true)
+
+  def write(file: File, bytes: Array[Byte]): Unit =
+    writeBytes(file, bytes, false)
+  private def writeBytes(file: File, bytes: Array[Byte], append: Boolean): Unit =
+    fileOutputStream(append)(file) { _.write(bytes) }
+
+
+  // Not optimized for large files
+  def readLines(file: File, charset: Charset = defaultCharset): List[String] =
+    fileReader(charset)(file)(readLines)
+    
+  // Not optimized for large files
+  def readLines(in: BufferedReader): List[String] = 
+    foldLines[List[String]](in, Nil)( (accum, line) => line :: accum ).reverse
+  
+  def foreachLine(in: BufferedReader)(f: String => Unit): Unit =
+    foldLines(in, ())( (_, line) => f(line) )
+    
+  def foldLines[T](in: BufferedReader, init: T)(f: (T, String) => T): T =
+  {
+    def readLine(accum: T): T =
+    {
+      val line = in.readLine()
+      if(line eq null) accum else readLine(f(accum, line))
+    }
+    readLine(init)
+  }
+  
+  def writeLines(file: File, lines: Seq[String], charset: Charset = defaultCharset, append: Boolean = false): Unit =
+    writer(file, lines.headOption.getOrElse(""), charset, append) { w =>
+      lines.foreach { line => w.write(line); w.newLine() }
+    }
+    
+  def write(properties: Properties, label: String, to: File) =
+    fileOutputStream()(to) { output => properties.store(output, label) }
+  def load(properties: Properties, from: File): Unit =
+    if(from.exists)
+      fileInputStream(from){ input => properties.load(input) }
+
+  /** A pattern used to split a String by path separator characters.*/
+  private val PathSeparatorPattern = java.util.regex.Pattern.compile(File.pathSeparator)
+
+  /** Splits a String around path separator characters. */
+  def pathSplit(s: String) = PathSeparatorPattern.split(s)
+
+  /** Move the provided files to a temporary location.
+  *   If 'f' returns normally, delete the files.
+  *   If 'f' throws an Exception, return the files to their original location.*/
+  def stash[T](files: Set[File])(f: => T): T =
+    withTemporaryDirectory { dir =>
+      val stashed = stashLocations(dir, files.toArray)
+      move(stashed)
+
+      try { f } catch { case e: Exception =>
+        try { move(stashed.map(_.swap)); throw e }
+        catch { case _: Exception => throw e }
+      }
+    }
+
+  private def stashLocations(dir: File, files: Array[File]) =
+    for( (file, index) <- files.zipWithIndex) yield
+      (file, new File(dir, index.toHexString))
+
+  def move(files: Traversable[(File, File)]): Unit =
+    files.foreach(Function.tupled(move))
+    
+  def move(a: File, b: File): Unit =
+  {
+    if(b.exists)
+      delete(b)
+    if(!a.renameTo(b))
+    {
+      copyFile(a, b, true)
+      delete(a)
+    }
+  }
+
+  def gzipFileOut[T](file: File)(f: OutputStream => T): T =
+    Using.fileOutputStream()(file) { fout =>
+    Using.gzipOutputStream(fout) { outg =>
+    Using.bufferedOutputStream(outg)(f) }}
+
+  def gzipFileIn[T](file: File)(f: InputStream => T): T =
+    Using.fileInputStream(file) { fin =>
+    Using.gzipInputStream(fin) { ing =>
+    Using.bufferedInputStream(ing)(f) }}
 }