    fs = require 'fs'
    async = require 'async'
    
    utils = require '../../lib/utils'
    notify = require '../../lib/notify'
    log = require '../../lib/log'
    notifications = require './notifications'
    sources = require './sources'

    types = ['js', 'css', 'img']

First method called on this module. Verify the Pages file exists.

    install = (cb) -> 

      ok = false

_todo_ Error on assets not found, etc.

      downloadDependencies () ->

        ok = true 

        cb()

    validateCredentials = () ->

      throw new Error 'Private repo specified, but no `PAGES_GITHUB_USERNAME` env var set.'  if !process.env.PAGES_GITHUB_USERNAME or process.env.PAGES_GITHUB_USERNAME is ''
      throw new Error 'Private repo specified, but no `PAGES_GITHUB_PASSWORD` env var set.'  if !process.env.PAGES_GITHUB_PASSWORD or process.env.PAGES_GITHUB_PASSWORD is ''
    
Handle the different dependency types and how we fetch them.

    downloadDependencies = (cb) ->

      commands = []

      for folder,depDef of sources.getVendorDependencies()

        validateCredentials()  if depDef.private

        switch depDef.type

          when 'github'

            if depDef.release and depDef.release isnt 'latest'

              cachedReleasePath = "#{process.env.HOME}/.pages/deps/#{depDef.path.split('/')[0]}-#{depDef.path.split('/')[1]}-#{depDef.release}.zip"

              cached = fs.existsSync cachedReleasePath

              if cached 

                commands.push "cp #{cachedReleasePath} #{process.cwd()}/_app/vendor/#{folder}.zip" 

              else

We have to do some name manipulation based to conform to Pages conventions.

                commands.push "wget https://github.com/#{depDef.path}/archive/#{depDef.release}.zip -O #{process.cwd()}/_app/vendor/#{folder}.zip" 
                commands.push "cp #{process.cwd()}/_app/vendor/#{folder}.zip #{cachedReleasePath}"

              commands.push "unzip #{process.cwd()}/_app/vendor/#{folder}.zip -d #{process.cwd()}/_app/vendor/" 

Change the folder name to the asset we specified, instead of `<repo>-<release>`. Not sure why Github removes the `v` attribute.
              
              depDef.release = depDef.release.replace('v', '')  if depDef.release.indexOf('v') isnt -1
              commands.push "mv #{process.cwd()}/_app/vendor/#{depDef.path.split('/')[1]}-#{depDef.release} #{process.cwd()}/_app/vendor/#{folder}" 

            else 

Whatever branch is referenced as master will be downloaded.

              commandSegment = "https://api.github.com/repos/#{depDef.path}/tarball -L -o #{process.cwd()}/_app/vendor/#{folder}.tar.gz"

              if depDef.private then command = "curl -u '#{process.env.PAGES_GITHUB_USERNAME}:#{process.env.PAGES_GITHUB_PASSWORD}' #{commandSegment}" else command = "curl #{commandSegment}"
          
              commands.push command

              commands.push "mkdir #{process.cwd()}/_app/vendor/#{folder}"
              commands.push "tar -xjvf #{process.cwd()}/_app/vendor/#{folder}.tar.gz -C #{process.cwd()}/_app/vendor/#{folder} --strip 1" 

          when 'gist'
            
            if depDef.private then command = "git clone https://#{process.env.PAGES_GITHUB_USERNAME}:#{process.env.PAGES_GITHUB_PASSWORD}@gist.github.com/#{depDef.path.split('/')[1]}.git #{process.cwd()}/_app/vendor/#{folder}" else command = "git clone https://gist.github.com/#{depDef.path.split('/')[1]}.git #{process.cwd()}/_app/vendor/#{folder}"

            commands.push command

          when 'localhost'

            types = ['js', 'css']

            for type in types 

              if depDef.include and depDef.include[type]

                assetsDef = depDef.include[type]

                continue  if !assetsDef

                commands.push "mkdir #{process.cwd()}/_app/vendor/#{folder}"

                for assetDef in assetsDef

                  commands.push "cp #{process.cwd()}/#{assetDef.asset} #{process.cwd()}/_app/vendor/#{folder}/#{assetDef.asset.split('/')[assetDef.asset.split('/').length - 1]}"

          when 'external'

            types = ['js', 'css', 'img']

            for type in types 

              if depDef.include and depDef.include[type]

                assetsDef = depDef.include[type]

                continue  if !assetsDef

                for assetDef in assetsDef

                  commands.push "curl #{assetDef.asset} --create-dirs -L -o #{process.cwd()}/_app/vendor/#{folder}/#{assetDef.asset.split('/')[assetDef.asset.split('/').length - 1]}"

      console.log JSON.stringify(commands: commands, null, 2)
      
      commandWrapper = (command, done) -> setTimeout (-> utils.runWithOutputAndCb command, notifications.compiler, () -> done() ), 500

We may not have this yet, so it _possibly_ needs to be created. 

      utils.runWithCb "mkdir #{process.cwd()}/_app", () -> 

      setTimeout (-> 

        utils.runWithCb "mkdir #{process.cwd()}/_app/vendor", () -> setTimeout (-> async.eachSeries commands, commandWrapper, () -> cb() ), 1 * 1000

      ), 1 * 1000

Remove all non-declared _Resource Types_

    cleanup = (cb) -> 

      filesToKeep = []

      getAsArray = (objArray) -> 

        arr = []

        arr.push dependency.file for dependency in objArray

        arr

      Array::push.apply filesToKeep, getAsArray(sources.vendor.js())
      Array::push.apply filesToKeep, getAsArray(sources.vendor.css())
      Array::push.apply filesToKeep, getAsArray(sources.vendor.img())

Running this `asynchronously`, we run into `ulimit` issues.

      utils.listFiles "#{process.cwd()}/_app/vendor", undefined, (files) -> 

Make sure we don't have a resource in here.

        filesToRemove = files.filter (file) -> filesToKeep.indexOf(file) is -1

        commands = filesToRemove.map (file) -> "rm #{file}"

        pause = (command, done) -> setTimeout (-> utils.runWithCb command, () -> done() ), 25

Run these in the background.

        async.eachSeries commands, pause, () -> log.info deps: 'Finished removing erroneous files.'

        cb()

Inject the AngularJS Modules into the built `app.litcoffee` file.

    injectAndBuild = (cb) ->

      to = "#{process.cwd()}/_app/app.litcoffee"

      if global.pages.opts.template then from = "#{process.env.HOME}/.pages/app.litcoffee" else from = "#{global.pkgBasePath}/lib/generate/app.litcoffee"

      utils.copyFile 
        from: from
        to: to
      , () -> 

        utils.replaceStringInFile to, 'APPNAME', require("#{process.cwd()}/pages").name
        utils.replaceStringInFile to, 'MODULES', "#{JSON.stringify(sources.angular())}"
          
        cb()

## Public API ##

    publicFns = 
      install: install
      cleanup: cleanup
      injectAndBuild: injectAndBuild

    module.exports = publicFns