text: /*
   * grunt
   * http://gruntjs.com/
   *
   * Copyright (c) 2014 "Cowboy" Ben Alman
   * Licensed under the MIT license.
   * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
   */
  
  'use strict';
  
  // Nodejs libs.
  var path = require('path');
  
  // This allows grunt to require() .coffee files.
  require('coffee-script');
  
  // The module to be exported.
  var grunt = module.exports = {};
  
  // Expose internal grunt libs.
  function gRequire(name) {
    return grunt[name] = require('./grunt/' + name);
  }
  
  var util = require('grunt-legacy-util');
  grunt.util = util;
  grunt.util.task = require('./util/task');
  
  var Log = require('grunt-legacy-log').Log;
  var log = new Log({grunt: grunt});
  grunt.log = log;
  
  gRequire('template');
  gRequire('event');
  var fail = gRequire('fail');
  gRequire('file');
  var option = gRequire('option');
  var config = gRequire('config');
  var task = gRequire('task');
  var help = gRequire('help');
  gRequire('cli');
  var verbose = grunt.verbose = log.verbose;
  
  // Expose some grunt metadata.
  grunt.package = require('../package.json');
  grunt.version = grunt.package.version;
  
  // Expose specific grunt lib methods on grunt.
  function gExpose(obj, methodName, newMethodName) {
    grunt[newMethodName || methodName] = obj[methodName].bind(obj);
  }
  gExpose(task, 'registerTask');
  gExpose(task, 'registerMultiTask');
  gExpose(task, 'registerInitTask');
  gExpose(task, 'renameTask');
  gExpose(task, 'loadTasks');
  gExpose(task, 'loadNpmTasks');
  gExpose(config, 'init', 'initConfig');
  gExpose(fail, 'warn');
  gExpose(fail, 'fatal');
  
  // Expose the task interface. I've never called this manually, and have no idea
  // how it will work. But it might.
  grunt.tasks = function(tasks, options, done) {
    // Update options with passed-in options.
    option.init(options);
  
    // Display the grunt version and quit if the users did --version.
    var _tasks, _options;
    if (option('version')) {
      // Not --verbose.
      log.writeln('grunt v' + grunt.version);
  
      if (option('verbose')) {
        // --verbose
        verbose.writeln('Install path: ' + path.resolve(__dirname, '..'));
        // Yes, this is a total hack, but we don't want to log all that verbose
        // task initialization stuff here.
        grunt.log.muted = true;
        // Initialize task system so that available tasks can be listed.
        grunt.task.init([], {help: true});
        // Re-enable logging.
        grunt.log.muted = false;
  
        // Display available tasks (for shell completion, etc).
        _tasks = Object.keys(grunt.task._tasks).sort();
        verbose.writeln('Available tasks: ' + _tasks.join(' '));
  
        // Display available options (for shell completion, etc).
        _options = [];
        Object.keys(grunt.cli.optlist).forEach(function(long) {
          var o = grunt.cli.optlist[long];
          _options.push('--' + (o.negate ? 'no-' : '') + long);
          if (o.short) { _options.push('-' + o.short); }
        });
        verbose.writeln('Available options: ' + _options.join(' '));
      }
  
      return;
    }
  
    // Init colors.
    log.initColors();
  
    // Display help and quit if the users did --help.
    if (option('help')) {
      help.display();
      return;
    }
  
    // A little header stuff.
    verbose.header('Initializing').writeflags(option.flags(), 'Command-line options');
  
    // Determine and output which tasks will be run.
    var tasksSpecified = tasks && tasks.length > 0;
    tasks = task.parseArgs([tasksSpecified ? tasks : 'default']);
  
    // Initialize tasks.
    task.init(tasks);
  
    verbose.writeln();
    if (!tasksSpecified) {
      verbose.writeln('No tasks specified, running default tasks.');
    }
    verbose.writeflags(tasks, 'Running tasks');
  
    // Handle otherwise unhandleable (probably asynchronous) exceptions.
    var uncaughtHandler = function(e) {
      fail.fatal(e, fail.code.TASK_FAILURE);
    };
    process.on('uncaughtException', uncaughtHandler);
  
    // Report, etc when all tasks have completed.
    task.options({
      error: function(e) {
        fail.warn(e, fail.code.TASK_FAILURE);
      },
      done: function() {
        // Stop handling uncaught exceptions so that we don't leave any
        // unwanted process-level side effects behind. There is no need to do
        // this in the error callback, because fail.warn() will either kill
        // the process, or with --force keep on going all the way here.
        process.removeListener('uncaughtException', uncaughtHandler);
  
        // Output a final fail / success report.
        fail.report();
  
        if (done) {
          // Execute "done" function when done (only if passed, of course).
          done();
        } else {
          // Otherwise, explicitly exit.
          util.exit(0);
        }
      }
    });
  
    // Execute all tasks, in order. Passing each task individually in a forEach
    // allows the error callback to execute multiple times.
    tasks.forEach(function(name) { task.run(name); });
    // Run tasks async internally to reduce call-stack, per:
    // https://github.com/gruntjs/grunt/pull/1026
    task.start({asyncDone:true});
  };
  