       else
         @emit 'end'
 
+  # Fetch a single file and write it to disk.
+  getFile: (file, done) =>
+    url = @url(file)
+    logging.info "fetching #{url}"
 
-install = (repo, version='master') ->
-  pkg = new Package(repo, version)
-  pkg.install()
+    @emit 'file', file, url
+    dst = @join(file)
+    fs.mkdirSync sysPath.dirname(dst)
 
-module.exports = {install}
+    # download file and save to disk
+    request.get url, dst, (err, res) ->
+      if err then console.log "Problem with request #{err.message}"
+
+  # Write a file to disk.
+  writeFile: (file, str, callback) ->
+    file = @join(file)
+    logging.info "writing file #{file}"
+    fs.writeFile file, str, callback
+
+  # Install dependencies,
+  getDependencies: (deps, callback) ->
+    pkgs = []
+    for name, version of deps
+      pkg = new Package(name, version)
+      pkgs.push pkg
+
+    getPkg = (pkg, done) =>
+      pkg.on 'end', done
+      pkg.install()
+
+    async.each pkgs, getPkg, callback
+
+# Package Manager
+class PackageManager
+
+  install: (repo, version) ->
+    pkg = new Package(repo, version)
+    pkg.install()
+
+# Freeze the object so it can't be modified later.
+module.exports = Object.freeze(new PackageManager())

  url: (file) ->
    "#{@remote}/#{@repo}/#{@version}/#{file}"

  # Get local json if the component is installed
  getLocalJSON: (callback) ->
    path = @join('component.json')
    fs.readFile path, 'utf8', (err, json) ->
      if err
        return callback(err)
      try
        json = JSON.parse(json)
      catch err
        err.message += " in #{path}"
        return callback(err)
      callback(null, json)

  # Get component.json
  getJSON: (done) ->
    url = @url('component.json')


    else
      @version = version

    # The default version is `master`.
    @version = 'master' if not @version or @version is '*'
    logging.info "Installing #{@repo}@#{@version}..."

    @remote = 'https://raw.github.com'
    @slug = "#{@repo}@#{@version}"

    # Use `repo@version` to de-duplicate in-flight requests.
    if inFlight[@slug]
      @install = @emit.bind(@, 'end')
    inFlight[@slug] = true
