Index: Dev/trunk/node_modules/grunt/.npmignore
===================================================================
--- Dev/trunk/node_modules/grunt/.npmignore	(revision 484)
+++ Dev/trunk/node_modules/grunt/.npmignore	(revision 516)
@@ -4,5 +4,5 @@
 AUTHORS
 CHANGELOG
-CONTRIBUTING.MD
+CONTRIBUTING.md
 custom-gruntfile.js
 Gruntfile.js
Index: Dev/trunk/node_modules/grunt/CONTRIBUTING.md
===================================================================
--- Dev/trunk/node_modules/grunt/CONTRIBUTING.md	(revision 484)
+++ 	(revision )
@@ -1,1 +1,0 @@
-Please see the [Contributing to grunt](http://gruntjs.com/contributing) guide for information on contributing to this project.
Index: Dev/trunk/node_modules/grunt/LICENSE-MIT
===================================================================
--- Dev/trunk/node_modules/grunt/LICENSE-MIT	(revision 484)
+++ Dev/trunk/node_modules/grunt/LICENSE-MIT	(revision 516)
@@ -1,3 +1,3 @@
-Copyright (c) 2013 "Cowboy" Ben Alman
+Copyright (c) 2014 "Cowboy" Ben Alman
 
 Permission is hereby granted, free of charge, to any person
Index: Dev/trunk/node_modules/grunt/README.md
===================================================================
--- Dev/trunk/node_modules/grunt/README.md	(revision 484)
+++ Dev/trunk/node_modules/grunt/README.md	(revision 516)
@@ -1,3 +1,6 @@
-# Grunt: The JavaScript Task Runner [![Build Status](https://secure.travis-ci.org/gruntjs/grunt.png?branch=master)](http://travis-ci.org/gruntjs/grunt)
+# Grunt: The JavaScript Task Runner
+
+[![Build Status](https://secure.travis-ci.org/gruntjs/grunt.png?branch=master)](http://travis-ci.org/gruntjs/grunt)
+[![Built with Grunt](https://cdn.gruntjs.com/builtwith.png)](http://gruntjs.com/)
 
 <img align="right" height="260" src="http://gruntjs.com/img/grunt-logo-no-wordmark.svg">
Index: Dev/trunk/node_modules/grunt/internal-tasks/bump.js
===================================================================
--- Dev/trunk/node_modules/grunt/internal-tasks/bump.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/internal-tasks/bump.js	(revision 516)
@@ -3,5 +3,5 @@
  * http://gruntjs.com/
  *
- * Copyright (c) 2013 "Cowboy" Ben Alman, contributors
+ * Copyright (c) 2014 "Cowboy" Ben Alman, contributors
  * Licensed under the MIT license.
  */
Index: Dev/trunk/node_modules/grunt/internal-tasks/subgrunt.js
===================================================================
--- Dev/trunk/node_modules/grunt/internal-tasks/subgrunt.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/internal-tasks/subgrunt.js	(revision 516)
@@ -3,5 +3,5 @@
  * http://gruntjs.com/
  *
- * Copyright (c) 2013 "Cowboy" Ben Alman
+ * Copyright (c) 2014 "Cowboy" Ben Alman
  * Licensed under the MIT license.
  * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
Index: Dev/trunk/node_modules/grunt/lib/grunt.js
===================================================================
--- Dev/trunk/node_modules/grunt/lib/grunt.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/lib/grunt.js	(revision 516)
@@ -3,5 +3,5 @@
  * http://gruntjs.com/
  *
- * Copyright (c) 2013 "Cowboy" Ben Alman
+ * Copyright (c) 2014 "Cowboy" Ben Alman
  * Licensed under the MIT license.
  * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
@@ -23,5 +23,9 @@
   return grunt[name] = require('./grunt/' + name);
 }
-var util = gRequire('util');
+
+var util = require('grunt-legacy-util');
+grunt.util = util;
+grunt.util.task = require('./util/task');
+
 gRequire('template');
 gRequire('event');
@@ -153,4 +157,6 @@
   // allows the error callback to execute multiple times.
   tasks.forEach(function(name) { task.run(name); });
-  task.start();
+  // Run tasks async internally to reduce call-stack, per:
+  // https://github.com/gruntjs/grunt/pull/1026
+  task.start({asyncDone:true});
 };
Index: Dev/trunk/node_modules/grunt/lib/grunt/cli.js
===================================================================
--- Dev/trunk/node_modules/grunt/lib/grunt/cli.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/lib/grunt/cli.js	(revision 516)
@@ -3,5 +3,5 @@
  * http://gruntjs.com/
  *
- * Copyright (c) 2013 "Cowboy" Ben Alman
+ * Copyright (c) 2014 "Cowboy" Ben Alman
  * Licensed under the MIT license.
  * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
@@ -22,5 +22,5 @@
   // CLI-parsed options override any passed-in "default" options.
   if (options) {
-    // For each defult option...
+    // For each default option...
     Object.keys(options).forEach(function(key) {
       if (!(key in cli.options)) {
@@ -62,5 +62,5 @@
     short: 'd',
     info: 'Enable debugging mode for tasks that support it.',
-    type: Number
+    type: [Number, Boolean]
   },
   stack: {
Index: Dev/trunk/node_modules/grunt/lib/grunt/config.js
===================================================================
--- Dev/trunk/node_modules/grunt/lib/grunt/config.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/lib/grunt/config.js	(revision 516)
@@ -3,5 +3,5 @@
  * http://gruntjs.com/
  *
- * Copyright (c) 2013 "Cowboy" Ben Alman
+ * Copyright (c) 2014 "Cowboy" Ben Alman
  * Licensed under the MIT license.
  * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
Index: Dev/trunk/node_modules/grunt/lib/grunt/event.js
===================================================================
--- Dev/trunk/node_modules/grunt/lib/grunt/event.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/lib/grunt/event.js	(revision 516)
@@ -3,5 +3,5 @@
  * http://gruntjs.com/
  *
- * Copyright (c) 2013 "Cowboy" Ben Alman
+ * Copyright (c) 2014 "Cowboy" Ben Alman
  * Licensed under the MIT license.
  * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
Index: Dev/trunk/node_modules/grunt/lib/grunt/fail.js
===================================================================
--- Dev/trunk/node_modules/grunt/lib/grunt/fail.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/lib/grunt/fail.js	(revision 516)
@@ -3,5 +3,5 @@
  * http://gruntjs.com/
  *
- * Copyright (c) 2013 "Cowboy" Ben Alman
+ * Copyright (c) 2014 "Cowboy" Ben Alman
  * Licensed under the MIT license.
  * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
Index: Dev/trunk/node_modules/grunt/lib/grunt/file.js
===================================================================
--- Dev/trunk/node_modules/grunt/lib/grunt/file.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/lib/grunt/file.js	(revision 516)
@@ -3,5 +3,5 @@
  * http://gruntjs.com/
  *
- * Copyright (c) 2013 "Cowboy" Ben Alman
+ * Copyright (c) 2014 "Cowboy" Ben Alman
  * Licensed under the MIT license.
  * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
@@ -134,7 +134,15 @@
 var pathSeparatorRe = /[\/\\]/g;
 
+// The "ext" option refers to either everything after the first dot (default)
+// or everything after the last dot.
+var extDotRe = {
+  first: /(\.[^\/]*)?$/,
+  last: /(\.[^\/\.]*)?$/,
+};
+
 // Build a multi task "files" object dynamically.
 file.expandMapping = function(patterns, destBase, options) {
   options = grunt.util._.defaults({}, options, {
+    extDot: 'first',
     rename: function(destBase, destPath) {
       return path.join(destBase || '', destPath);
@@ -151,6 +159,6 @@
     }
     // Change the extension?
-    if (options.ext) {
-      destPath = destPath.replace(/(\.[^\/]*)?$/, options.ext);
+    if ('ext' in options) {
+      destPath = destPath.replace(extDotRe[options.extDot], options.ext);
     }
     // Generate destination filename.
Index: Dev/trunk/node_modules/grunt/lib/grunt/help.js
===================================================================
--- Dev/trunk/node_modules/grunt/lib/grunt/help.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/lib/grunt/help.js	(revision 516)
@@ -3,5 +3,5 @@
  * http://gruntjs.com/
  *
- * Copyright (c) 2013 "Cowboy" Ben Alman
+ * Copyright (c) 2014 "Cowboy" Ben Alman
  * Licensed under the MIT license.
  * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
Index: Dev/trunk/node_modules/grunt/lib/grunt/log.js
===================================================================
--- Dev/trunk/node_modules/grunt/lib/grunt/log.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/lib/grunt/log.js	(revision 516)
@@ -3,5 +3,5 @@
  * http://gruntjs.com/
  *
- * Copyright (c) 2013 "Cowboy" Ben Alman
+ * Copyright (c) 2014 "Cowboy" Ben Alman
  * Licensed under the MIT license.
  * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
Index: Dev/trunk/node_modules/grunt/lib/grunt/option.js
===================================================================
--- Dev/trunk/node_modules/grunt/lib/grunt/option.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/lib/grunt/option.js	(revision 516)
@@ -3,5 +3,5 @@
  * http://gruntjs.com/
  *
- * Copyright (c) 2013 "Cowboy" Ben Alman
+ * Copyright (c) 2014 "Cowboy" Ben Alman
  * Licensed under the MIT license.
  * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
Index: Dev/trunk/node_modules/grunt/lib/grunt/task.js
===================================================================
--- Dev/trunk/node_modules/grunt/lib/grunt/task.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/lib/grunt/task.js	(revision 516)
@@ -3,5 +3,5 @@
  * http://gruntjs.com/
  *
- * Copyright (c) 2013 "Cowboy" Ben Alman
+ * Copyright (c) 2014 "Cowboy" Ben Alman
  * Licensed under the MIT license.
  * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
@@ -108,5 +108,5 @@
       }
     } else if (Array.isArray(data.files)) {
-      data.files.forEach(function(obj) {
+      grunt.util._.flatten(data.files).forEach(function(obj) {
         var prop;
         if ('src' in obj || 'dest' in obj) {
@@ -245,4 +245,9 @@
       return options;
     };
+    // Expose the current target.
+    this.target = target;
+    // Recreate flags object so that the target isn't set as a flag.
+    this.flags = {};
+    this.args.forEach(function(arg) { this.flags[arg] = true; }, this);
     // Expose data on `this` (as well as task.current).
     this.data = grunt.config([name, target]);
@@ -256,9 +261,4 @@
       }.bind(this)
     });
-    // Expose the current target.
-    this.target = target;
-    // Recreate flags object so that the target isn't set as a flag.
-    this.flags = {};
-    this.args.forEach(function(arg) { this.flags[arg] = true; }, this);
     // Call original task function, passing in the target and any other args.
     return fn.apply(this, this.args);
@@ -278,9 +278,16 @@
 // Override built-in renameTask to use the registry.
 task.renameTask = function(oldname, newname) {
-  // Add and remove task.
-  registry.untasks.push(oldname);
-  registry.tasks.push(newname);
-  // Actually rename task.
-  return parent.renameTask.apply(task, arguments);
+  var result;
+  try {
+    // Actually rename task.
+    result = parent.renameTask.apply(task, arguments);
+    // Add and remove task.
+    registry.untasks.push(oldname);
+    registry.tasks.push(newname);
+    // Return result.
+    return result;
+  } catch(e) {
+    grunt.log.error(e.message);
+  }
 };
 
Index: Dev/trunk/node_modules/grunt/lib/grunt/template.js
===================================================================
--- Dev/trunk/node_modules/grunt/lib/grunt/template.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/lib/grunt/template.js	(revision 516)
@@ -3,5 +3,5 @@
  * http://gruntjs.com/
  *
- * Copyright (c) 2013 "Cowboy" Ben Alman
+ * Copyright (c) 2014 "Cowboy" Ben Alman
  * Licensed under the MIT license.
  * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
Index: Dev/trunk/node_modules/grunt/lib/grunt/util.js
===================================================================
--- Dev/trunk/node_modules/grunt/lib/grunt/util.js	(revision 484)
+++ 	(revision )
@@ -1,188 +1,0 @@
-/*
- * grunt
- * http://gruntjs.com/
- *
- * Copyright (c) 2013 "Cowboy" Ben Alman
- * Licensed under the MIT license.
- * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
- */
-
-'use strict';
-
-// Nodejs libs.
-var spawn = require('child_process').spawn;
-var nodeUtil = require('util');
-var path = require('path');
-
-// The module to be exported.
-var util = module.exports = {};
-
-// A few internal utilites, exposed.
-util.task = require('../util/task');
-util.namespace = require('getobject');
-
-// External libs.
-util.hooker = require('hooker');
-util.async = require('async');
-var _ = util._ = require('lodash');
-var which = require('which').sync;
-// Instead of process.exit. See https://github.com/cowboy/node-exit
-util.exit = require('exit');
-
-// Mixin Underscore.string methods.
-_.str = require('underscore.string');
-_.mixin(_.str.exports());
-
-// Return a function that normalizes the given function either returning a
-// value or accepting a "done" callback that accepts a single value.
-util.callbackify = function(fn) {
-  return function callbackable() {
-    // Invoke original function, getting its result.
-    var result = fn.apply(this, arguments);
-    // If the same number or less arguments were specified than fn accepts,
-    // assume the "done" callback was already handled.
-    var length = arguments.length;
-    if (length === fn.length) { return; }
-    // Otherwise, if the last argument is a function, assume it is a "done"
-    // callback and call it.
-    var done = arguments[length - 1];
-    if (typeof done === 'function') { done(result); }
-  };
-};
-
-// Create a new Error object, with an origError property that will be dumped
-// if grunt was run with the --debug=9 option.
-util.error = function(err, origError) {
-  if (!nodeUtil.isError(err)) { err = new Error(err); }
-  if (origError) { err.origError = origError; }
-  return err;
-};
-
-// The line feed char for the current system.
-util.linefeed = process.platform === 'win32' ? '\r\n' : '\n';
-
-// Normalize linefeeds in a string.
-util.normalizelf = function(str) {
-  return str.replace(/\r\n|\n/g, util.linefeed);
-};
-
-// What "kind" is a value?
-// I really need to rework https://github.com/cowboy/javascript-getclass
-var kindsOf = {};
-'Number String Boolean Function RegExp Array Date Error'.split(' ').forEach(function(k) {
-  kindsOf['[object ' + k + ']'] = k.toLowerCase();
-});
-util.kindOf = function(value) {
-  // Null or undefined.
-  if (value == null) { return String(value); }
-  // Everything else.
-  return kindsOf[kindsOf.toString.call(value)] || 'object';
-};
-
-// Coerce something to an Array.
-util.toArray = Function.call.bind(Array.prototype.slice);
-
-// Return the string `str` repeated `n` times.
-util.repeat = function(n, str) {
-  return new Array(n + 1).join(str || ' ');
-};
-
-// Given str of "a/b", If n is 1, return "a" otherwise "b".
-util.pluralize = function(n, str, separator) {
-  var parts = str.split(separator || '/');
-  return n === 1 ? (parts[0] || '') : (parts[1] || '');
-};
-
-// Recurse through objects and arrays, executing fn for each non-object.
-util.recurse = function recurse(value, fn, fnContinue) {
-  var obj;
-  if (fnContinue && fnContinue(value) === false) {
-    // Skip value if necessary.
-    return value;
-  } else if (util.kindOf(value) === 'array') {
-    // If value is an array, recurse.
-    return value.map(function(value) {
-      return recurse(value, fn, fnContinue);
-    });
-  } else if (util.kindOf(value) === 'object') {
-    // If value is an object, recurse.
-    obj = {};
-    Object.keys(value).forEach(function(key) {
-      obj[key] = recurse(value[key], fn, fnContinue);
-    });
-    return obj;
-  } else {
-    // Otherwise pass value into fn and return.
-    return fn(value);
-  }
-};
-
-// Spawn a child process, capturing its stdout and stderr.
-util.spawn = function(opts, done) {
-  // Build a result object and pass it (among other things) into the
-  // done function.
-  var callDone = function(code, stdout, stderr) {
-    // Remove trailing whitespace (newline)
-    stdout = _.rtrim(stdout);
-    stderr = _.rtrim(stderr);
-    // Create the result object.
-    var result = {
-      stdout: stdout,
-      stderr: stderr,
-      code: code,
-      toString: function() {
-        if (code === 0) {
-          return stdout;
-        } else if ('fallback' in opts) {
-          return opts.fallback;
-        } else if (opts.grunt) {
-          // grunt.log.error uses standard out, to be fixed in 0.5.
-          return stderr || stdout;
-        }
-        return stderr;
-      }
-    };
-    // On error (and no fallback) pass an error object, otherwise pass null.
-    done(code === 0 || 'fallback' in opts ? null : new Error(stderr), result, code);
-  };
-
-  var cmd, args;
-  var pathSeparatorRe = /[\\\/]/g;
-  if (opts.grunt) {
-    cmd = process.argv[0];
-    args = [process.argv[1]].concat(opts.args);
-  } else {
-    // On Windows, child_process.spawn will only file .exe files in the PATH,
-    // not other executable types (grunt issue #155).
-    try {
-      if (!pathSeparatorRe.test(opts.cmd)) {
-        // Only use which if cmd has no path component.
-        cmd = which(opts.cmd);
-      } else {
-        cmd = opts.cmd.replace(pathSeparatorRe, path.sep);
-      }
-    } catch (err) {
-      callDone(127, '', String(err));
-      return;
-    }
-    args = opts.args;
-  }
-
-  var child = spawn(cmd, args, opts.opts);
-  var stdout = new Buffer('');
-  var stderr = new Buffer('');
-  if (child.stdout) {
-    child.stdout.on('data', function(buf) {
-      stdout = Buffer.concat([stdout, new Buffer(buf)]);
-    });
-  }
-  if (child.stderr) {
-    child.stderr.on('data', function(buf) {
-      stderr = Buffer.concat([stderr, new Buffer(buf)]);
-    });
-  }
-  child.on('close', function(code) {
-    callDone(code, stdout.toString(), stderr.toString());
-  });
-  return child;
-};
Index: Dev/trunk/node_modules/grunt/lib/util/task.js
===================================================================
--- Dev/trunk/node_modules/grunt/lib/util/task.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/lib/util/task.js	(revision 516)
@@ -3,5 +3,5 @@
  * http://gruntjs.com/
  *
- * Copyright (c) 2013 "Cowboy" Ben Alman
+ * Copyright (c) 2014 "Cowboy" Ben Alman
  * Licensed under the MIT license.
  * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
@@ -90,4 +90,7 @@
   // easier to implement than some kind of in-task "super" functionality.
   Task.prototype.renameTask = function(oldname, newname) {
+    if (!this._tasks[oldname]) {
+      throw new Error('Cannot rename missing "' + oldname + '" task.');
+    }
     // Rename task.
     this._tasks[newname] = this._tasks[oldname];
@@ -186,5 +189,5 @@
 
   // Run a task function, handling this.async / return value.
-  Task.prototype.runTaskFn = function(context, fn, done) {
+  Task.prototype.runTaskFn = function(context, fn, done, asyncDone) {
     // Async flag.
     var async = false;
@@ -213,5 +216,13 @@
         this._options.error.call({name: context.name, nameArgs: context.nameArgs}, err);
       }
-      done(err, success);
+      // only call done async if explicitly requested to
+      // see: https://github.com/gruntjs/grunt/pull/1026
+      if (asyncDone) {
+        process.nextTick(function () {
+          done(err, success);
+        });
+      } else {
+        done(err, success);
+      }
     }.bind(this);
 
@@ -244,5 +255,8 @@
 
   // Begin task queue processing. Ie. run all tasks.
-  Task.prototype.start = function() {
+  Task.prototype.start = function(opts) {
+    if (!opts) {
+      opts = {};
+    }
     // Abort if already running.
     if (this._running) { return false; }
@@ -281,5 +295,5 @@
       this.runTaskFn(context, function() {
         return thing.task.fn.apply(this, this.args);
-      }, nextTask);
+      }, nextTask, !!opts.asyncDone);
 
     }.bind(this);
Index: Dev/trunk/node_modules/grunt/node_modules/.bin/rimraf
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/.bin/rimraf	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/.bin/rimraf	(revision 516)
@@ -0,0 +1,1 @@
+link ../rimraf/bin.js
Index: Dev/trunk/node_modules/grunt/node_modules/colors/package.json
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/colors/package.json	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/colors/package.json	(revision 516)
@@ -26,9 +26,4 @@
   "readmeFilename": "ReadMe.md",
   "_id": "colors@0.6.2",
-  "dist": {
-    "shasum": "57915cf80820c121e254ec8b7819ab808d2beae5"
-  },
-  "_from": "colors@~0.6.2",
-  "_resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
-  "scripts": {}
+  "_from": "colors@~0.6.2"
 }
Index: Dev/trunk/node_modules/grunt/node_modules/eventemitter2/package.json
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/eventemitter2/package.json	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/eventemitter2/package.json	(revision 516)
@@ -59,8 +59,4 @@
   "homepage": "https://github.com/hij1nx/EventEmitter2",
   "_id": "eventemitter2@0.4.13",
-  "dist": {
-    "shasum": "2a03bdff50bda6586cf2e27c71feeaf6d37c383c"
-  },
-  "_from": "eventemitter2@~0.4.13",
-  "_resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.13.tgz"
+  "_from": "eventemitter2@~0.4.13"
 }
Index: Dev/trunk/node_modules/grunt/node_modules/exit/package.json
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/exit/package.json	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/exit/package.json	(revision 516)
@@ -48,8 +48,4 @@
   "readmeFilename": "README.md",
   "_id": "exit@0.1.2",
-  "dist": {
-    "shasum": "2a1f6b7dd67aedcf9544e948cc817113b64012a5"
-  },
-  "_from": "exit@~0.1.1",
-  "_resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz"
+  "_from": "exit@~0.1.1"
 }
Index: Dev/trunk/node_modules/grunt/node_modules/getobject/package.json
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/getobject/package.json	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/getobject/package.json	(revision 516)
@@ -45,8 +45,4 @@
   "readmeFilename": "README.md",
   "_id": "getobject@0.1.0",
-  "dist": {
-    "shasum": "4563bd9ebffaa0790ee7eec6e2d74523b7e852a6"
-  },
-  "_from": "getobject@~0.1.0",
-  "_resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz"
+  "_from": "getobject@~0.1.0"
 }
Index: Dev/trunk/node_modules/grunt/node_modules/glob/node_modules/inherits/package.json
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/glob/node_modules/inherits/package.json	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/glob/node_modules/inherits/package.json	(revision 516)
@@ -27,8 +27,5 @@
   "homepage": "https://github.com/isaacs/inherits",
   "_id": "inherits@1.0.0",
-  "dist": {
-    "shasum": "26467026b3b86de1c6f72f00d9a31b1c97077a92"
-  },
   "_from": "inherits@1",
-  "_resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.0.tgz"
+  "scripts": {}
 }
Index: Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/.npmignore
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/.npmignore	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/.npmignore	(revision 516)
@@ -0,0 +1,1 @@
+node_modules
Index: Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/Gruntfile.js
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/Gruntfile.js	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/Gruntfile.js	(revision 516)
@@ -0,0 +1,16 @@
+'use strict';
+
+module.exports = function(grunt) {
+
+  grunt.initConfig({
+    nodeunit: {
+      util: ['test/index.js']
+    },
+
+  });
+
+  grunt.loadNpmTasks('grunt-contrib-nodeunit');
+
+  grunt.registerTask('default', ['nodeunit']);
+
+};
Index: Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/LICENSE-MIT
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/LICENSE-MIT	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/LICENSE-MIT	(revision 516)
@@ -0,0 +1,22 @@
+Copyright (c) 2014 "Cowboy" Ben Alman
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
Index: Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/README.md
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/README.md	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/README.md	(revision 516)
@@ -0,0 +1,26 @@
+# grunt-legacy-util
+> Deprecated Grunt utils provided for backwards compatibility.
+
+`grunt.util.namespace` use [getobject]  
+`grunt.util.hooker` use [hooker]  
+`grunt.util.async` use [async]  
+`grunt.util._` use [lodash]  
+`grunt.util.exit` use [exit]  
+`grunt.util.callbackify`  
+`grunt.util.error`  
+`grunt.util.linefeed`  
+`grunt.util.normalizelf`  
+`grunt.util.kindOf` use [lodash]  
+`grunt.util.toArray`
+`grunt.util.repeat`  
+`grunt.util.pluralize`  
+`grunt.util.recurse` use [traverse]  
+`grunt.util.spawn`  
+
+
+[getobject]: https://www.npmjs.org/package/getobject
+[hooker]: https://www.npmjs.org/package/hooker
+[async]: https://www.npmjs.org/package/async
+[lodash]: https://www.npmjs.org/package/lodash
+[exit]: https://www.npmjs.org/package/exit
+[traverse]: https://www.npmjs.org/package/lodash
Index: Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/index.js
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/index.js	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/index.js	(revision 516)
@@ -0,0 +1,187 @@
+/*
+ * 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 spawn = require('child_process').spawn;
+var nodeUtil = require('util');
+var path = require('path');
+
+// The module to be exported.
+var util = module.exports = {};
+
+util.namespace = require('getobject');
+
+// External libs.
+util.hooker = require('hooker');
+util.async = require('async');
+var _ = util._ = require('lodash');
+var which = require('which').sync;
+// Instead of process.exit. See https://github.com/cowboy/node-exit
+util.exit = require('exit');
+
+// Mixin Underscore.string methods.
+_.str = require('underscore.string');
+_.mixin(_.str.exports());
+
+// Return a function that normalizes the given function either returning a
+// value or accepting a "done" callback that accepts a single value.
+util.callbackify = function(fn) {
+  return function callbackable() {
+    // Invoke original function, getting its result.
+    var result = fn.apply(this, arguments);
+    // If the same number or less arguments were specified than fn accepts,
+    // assume the "done" callback was already handled.
+    var length = arguments.length;
+    if (length === fn.length) { return; }
+    // Otherwise, if the last argument is a function, assume it is a "done"
+    // callback and call it.
+    var done = arguments[length - 1];
+    if (typeof done === 'function') { done(result); }
+  };
+};
+
+// Create a new Error object, with an origError property that will be dumped
+// if grunt was run with the --debug=9 option.
+util.error = function(err, origError) {
+  if (!nodeUtil.isError(err)) { err = new Error(err); }
+  if (origError) { err.origError = origError; }
+  return err;
+};
+
+// The line feed char for the current system.
+util.linefeed = process.platform === 'win32' ? '\r\n' : '\n';
+
+// Normalize linefeeds in a string.
+util.normalizelf = function(str) {
+  return str.replace(/\r\n|\n/g, util.linefeed);
+};
+
+// What "kind" is a value?
+// I really need to rework https://github.com/cowboy/javascript-getclass
+var kindsOf = {};
+'Number String Boolean Function RegExp Array Date Error'.split(' ').forEach(function(k) {
+  kindsOf['[object ' + k + ']'] = k.toLowerCase();
+});
+util.kindOf = function(value) {
+  // Null or undefined.
+  if (value == null) { return String(value); }
+  // Everything else.
+  return kindsOf[kindsOf.toString.call(value)] || 'object';
+};
+
+// Coerce something to an Array.
+util.toArray = Function.call.bind(Array.prototype.slice);
+
+// Return the string `str` repeated `n` times.
+util.repeat = function(n, str) {
+  return new Array(n + 1).join(str || ' ');
+};
+
+// Given str of "a/b", If n is 1, return "a" otherwise "b".
+util.pluralize = function(n, str, separator) {
+  var parts = str.split(separator || '/');
+  return n === 1 ? (parts[0] || '') : (parts[1] || '');
+};
+
+// Recurse through objects and arrays, executing fn for each non-object.
+util.recurse = function recurse(value, fn, fnContinue) {
+  var obj;
+  if (fnContinue && fnContinue(value) === false) {
+    // Skip value if necessary.
+    return value;
+  } else if (util.kindOf(value) === 'array') {
+    // If value is an array, recurse.
+    return value.map(function(value) {
+      return recurse(value, fn, fnContinue);
+    });
+  } else if (util.kindOf(value) === 'object') {
+    // If value is an object, recurse.
+    obj = {};
+    Object.keys(value).forEach(function(key) {
+      obj[key] = recurse(value[key], fn, fnContinue);
+    });
+    return obj;
+  } else {
+    // Otherwise pass value into fn and return.
+    return fn(value);
+  }
+};
+
+// Spawn a child process, capturing its stdout and stderr.
+util.spawn = function(opts, done) {
+  // Build a result object and pass it (among other things) into the
+  // done function.
+  var callDone = function(code, stdout, stderr) {
+    // Remove trailing whitespace (newline)
+    stdout = _.rtrim(stdout);
+    stderr = _.rtrim(stderr);
+    // Create the result object.
+    var result = {
+      stdout: stdout,
+      stderr: stderr,
+      code: code,
+      toString: function() {
+        if (code === 0) {
+          return stdout;
+        } else if ('fallback' in opts) {
+          return opts.fallback;
+        } else if (opts.grunt) {
+          // grunt.log.error uses standard out, to be fixed in 0.5.
+          return stderr || stdout;
+        }
+        return stderr;
+      }
+    };
+    // On error (and no fallback) pass an error object, otherwise pass null.
+    done(code === 0 || 'fallback' in opts ? null : new Error(stderr), result, code);
+  };
+
+  var cmd, args;
+  var pathSeparatorRe = /[\\\/]/g;
+  if (opts.grunt) {
+    cmd = process.execPath;
+    args = process.execArgv.concat(process.argv[1], opts.args);
+  } else {
+    // On Windows, child_process.spawn will only file .exe files in the PATH,
+    // not other executable types (grunt issue #155).
+    try {
+      if (!pathSeparatorRe.test(opts.cmd)) {
+        // Only use which if cmd has no path component.
+        cmd = which(opts.cmd);
+      } else {
+        cmd = opts.cmd.replace(pathSeparatorRe, path.sep);
+      }
+    } catch (err) {
+      callDone(127, '', String(err));
+      return;
+    }
+    args = opts.args || [];
+  }
+
+  var child = spawn(cmd, args, opts.opts);
+  var stdout = new Buffer('');
+  var stderr = new Buffer('');
+  if (child.stdout) {
+    child.stdout.on('data', function(buf) {
+      stdout = Buffer.concat([stdout, new Buffer(buf)]);
+    });
+  }
+  if (child.stderr) {
+    child.stderr.on('data', function(buf) {
+      stderr = Buffer.concat([stderr, new Buffer(buf)]);
+    });
+  }
+  child.on('close', function(code) {
+    callDone(code, stdout.toString(), stderr.toString());
+  });
+  return child;
+};
+
Index: Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/package.json
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/package.json	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/package.json	(revision 516)
@@ -0,0 +1,54 @@
+{
+  "name": "grunt-legacy-util",
+  "version": "0.1.2",
+  "description": "Deprecated Grunt utils provided for backwards compatibility.",
+  "author": {
+    "name": "\"Cowboy\" Ben Alman",
+    "url": "http://benalman.com/"
+  },
+  "homepage": "http://gruntjs.com/",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/gruntjs/grunt-legacy-util.git"
+  },
+  "bugs": {
+    "url": "http://github.com/gruntjs/grunt-legacy-util/issues"
+  },
+  "licenses": [
+    {
+      "type": "MIT",
+      "url": "http://github.com/gruntjs/grunt-legacy-util/blob/master/LICENSE-MIT"
+    }
+  ],
+  "main": "index.js",
+  "scripts": {
+    "test": "grunt test"
+  },
+  "engines": {
+    "node": ">= 0.8.0"
+  },
+  "keywords": [],
+  "dependencies": {
+    "hooker": "~0.2.3",
+    "async": "~0.1.22",
+    "lodash": "~0.9.2",
+    "exit": "~0.1.1",
+    "underscore.string": "~2.2.1",
+    "getobject": "~0.1.0",
+    "which": "~1.0.5"
+  },
+  "devDependencies": {
+    "grunt-contrib-jshint": "~0.6.4",
+    "grunt-contrib-nodeunit": "~0.2.0",
+    "grunt": "0.4.2",
+    "temporary": "0.0.8"
+  },
+  "readme": "# grunt-legacy-util\n> Deprecated Grunt utils provided for backwards compatibility.\n\n`grunt.util.namespace` use [getobject]  \n`grunt.util.hooker` use [hooker]  \n`grunt.util.async` use [async]  \n`grunt.util._` use [lodash]  \n`grunt.util.exit` use [exit]  \n`grunt.util.callbackify`  \n`grunt.util.error`  \n`grunt.util.linefeed`  \n`grunt.util.normalizelf`  \n`grunt.util.kindOf` use [lodash]  \n`grunt.util.toArray`\n`grunt.util.repeat`  \n`grunt.util.pluralize`  \n`grunt.util.recurse` use [traverse]  \n`grunt.util.spawn`  \n\n\n[getobject]: https://www.npmjs.org/package/getobject\n[hooker]: https://www.npmjs.org/package/hooker\n[async]: https://www.npmjs.org/package/async\n[lodash]: https://www.npmjs.org/package/lodash\n[exit]: https://www.npmjs.org/package/exit\n[traverse]: https://www.npmjs.org/package/lodash\n",
+  "readmeFilename": "README.md",
+  "_id": "grunt-legacy-util@0.1.2",
+  "dist": {
+    "shasum": "e1dbbcc204b3f3a744bb2e27cb028295a16d6e85"
+  },
+  "_from": "grunt-legacy-util@~0.1.2",
+  "_resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.1.2.tgz"
+}
Index: Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/Gruntfile-execArgv-child.js
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/Gruntfile-execArgv-child.js	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/Gruntfile-execArgv-child.js	(revision 516)
@@ -0,0 +1,7 @@
+module.exports = function(grunt) {
+
+  grunt.registerTask('default', function(text) {
+    console.log('OUTPUT: ' + process.execArgv.join(' '));
+  });
+
+};
Index: Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/Gruntfile-execArgv.js
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/Gruntfile-execArgv.js	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/Gruntfile-execArgv.js	(revision 516)
@@ -0,0 +1,17 @@
+module.exports = function(grunt) {
+
+  var util = require('../../');
+
+  grunt.registerTask('default', function(text) {
+    var done = this.async();
+    util.spawn({
+      grunt: true,
+      args: ['--gruntfile', 'Gruntfile-execArgv-child.js'],
+    }, function(err, result, code) {
+      var matches = result.stdout.match(/^(OUTPUT: .*)/m);
+      console.log(matches ? matches[1] : '');
+      done();
+    });
+  });
+
+};
Index: Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/Gruntfile-print-text.js
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/Gruntfile-print-text.js	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/Gruntfile-print-text.js	(revision 516)
@@ -0,0 +1,8 @@
+module.exports = function(grunt) {
+
+  grunt.registerTask('print', 'Print the specified text.', function(text) {
+    console.log('OUTPUT: ' + text);
+    // console.log(process.cwd());
+  });
+
+};
Index: Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/exec.cmd
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/exec.cmd	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/exec.cmd	(revision 516)
@@ -0,0 +1,1 @@
+@echo done
Index: Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/exec.sh
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/exec.sh	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/exec.sh	(revision 516)
@@ -0,0 +1,2 @@
+#!/bin/bash
+echo "done"
Index: Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/spawn-multibyte.js
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/spawn-multibyte.js	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/spawn-multibyte.js	(revision 516)
@@ -0,0 +1,17 @@
+// This is a test fixture for a case where spawn receives incomplete
+// multibyte strings in separate data events.
+
+// A multibyte buffer containing all our output. We will slice it later.
+// In this case we are using a Japanese word for hello / good day, where each
+// character takes three bytes.
+var fullOutput = new Buffer('ããã«ã¡ã¯');
+
+// Output one full character and one third of a character
+process.stdout.write(fullOutput.slice(0, 4));
+
+// Output the rest of the string
+process.stdout.write(fullOutput.slice(4));
+
+// Do the same for stderr
+process.stderr.write(fullOutput.slice(0, 4));
+process.stderr.write(fullOutput.slice(4));
Index: Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/spawn.js
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/spawn.js	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/spawn.js	(revision 516)
@@ -0,0 +1,8 @@
+
+var code = Number(process.argv[2]);
+
+process.stdout.write('stdout\n');
+process.stderr.write('stderr\n');
+
+// Instead of process.exit. See https://github.com/cowboy/node-exit
+require('exit')(code);
Index: Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/index.js
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/index.js	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/grunt-legacy-util/test/index.js	(revision 516)
@@ -0,0 +1,313 @@
+'use strict';
+
+var util = require('../');
+
+var fs = require('fs');
+var path = require('path');
+
+var Tempfile = require('temporary/lib/file');
+
+exports['util.callbackify'] = {
+  'return': function(test) {
+    test.expect(1);
+    // This function returns a value.
+    function add(a, b) {
+      return a + b;
+    }
+    util.callbackify(add)(1, 2, function(result) {
+      test.equal(result, 3, 'should be the correct result.');
+      test.done();
+    });
+  },
+  'callback (sync)': function(test) {
+    test.expect(1);
+    // This function accepts a callback which it calls synchronously.
+    function add(a, b, done) {
+      done(a + b);
+    }
+    util.callbackify(add)(1, 2, function(result) {
+      test.equal(result, 3, 'should be the correct result.');
+      test.done();
+    });
+  },
+  'callback (async)': function(test) {
+    test.expect(1);
+    // This function accepts a callback which it calls asynchronously.
+    function add(a, b, done) {
+      setTimeout(done.bind(null, a + b), 0);
+    }
+    util.callbackify(add)(1, 2, function(result) {
+      test.equal(result, 3, 'should be the correct result.');
+      test.done();
+    });
+  }
+};
+
+exports['util'] = {
+  'error': function(test) {
+    test.expect(9);
+    var origError = new Error('Original error.');
+
+    var err = util.error('Test message.');
+    test.ok(err instanceof Error, 'Should be an Error.');
+    test.equal(err.name, 'Error', 'Should be an Error.');
+    test.equal(err.message, 'Test message.', 'Should have the correct message.');
+
+    err = util.error('Test message.', origError);
+    test.ok(err instanceof Error, 'Should be an Error.');
+    test.equal(err.name, 'Error', 'Should be an Error.');
+    test.equal(err.message, 'Test message.', 'Should have the correct message.');
+    test.equal(err.origError, origError, 'Should reflect the original error.');
+
+    var newError = new Error('Test message.');
+    err = util.error(newError, origError);
+    test.equal(err, newError, 'Should be the passed-in Error.');
+    test.equal(err.origError, origError, 'Should reflect the original error.');
+    test.done();
+  },
+  'linefeed': function(test) {
+    test.expect(1);
+    if (process.platform === 'win32') {
+      test.equal(util.linefeed, '\r\n', 'linefeed should be operating-system appropriate.');
+    } else {
+      test.equal(util.linefeed, '\n', 'linefeed should be operating-system appropriate.');
+    }
+    test.done();
+  },
+  'normalizelf': function(test) {
+    test.expect(1);
+    if (process.platform === 'win32') {
+      test.equal(util.normalizelf('foo\nbar\r\nbaz\r\n\r\nqux\n\nquux'), 'foo\r\nbar\r\nbaz\r\n\r\nqux\r\n\r\nquux', 'linefeeds should be normalized');
+    } else {
+      test.equal(util.normalizelf('foo\nbar\r\nbaz\r\n\r\nqux\n\nquux'), 'foo\nbar\nbaz\n\nqux\n\nquux', 'linefeeds should be normalized');
+    }
+    test.done();
+  }
+};
+
+exports['util.spawn'] = {
+  setUp: function(done) {
+    this.script = path.resolve('test/fixtures/spawn.js');
+    done();
+  },
+  'exit code 0': function(test) {
+    test.expect(6);
+    util.spawn({
+      cmd: process.execPath,
+      args: [ this.script, 0 ],
+    }, function(err, result, code) {
+      test.equals(err, null);
+      test.equals(code, 0);
+      test.equals(result.stdout, 'stdout');
+      test.equals(result.stderr, 'stderr');
+      test.equals(result.code, 0);
+      test.equals(String(result), 'stdout');
+      test.done();
+    });
+  },
+  'exit code 0, fallback': function(test) {
+    test.expect(6);
+    util.spawn({
+      cmd: process.execPath,
+      args: [ this.script, 0 ],
+      fallback: 'ignored if exit code is 0'
+    }, function(err, result, code) {
+      test.equals(err, null);
+      test.equals(code, 0);
+      test.equals(result.stdout, 'stdout');
+      test.equals(result.stderr, 'stderr');
+      test.equals(result.code, 0);
+      test.equals(String(result), 'stdout');
+      test.done();
+    });
+  },
+  'non-zero exit code': function(test) {
+    test.expect(7);
+    util.spawn({
+      cmd: process.execPath,
+      args: [ this.script, 123 ],
+    }, function(err, result, code) {
+      test.ok(err instanceof Error);
+      test.equals(err.message, 'stderr');
+      test.equals(code, 123);
+      test.equals(result.stdout, 'stdout');
+      test.equals(result.stderr, 'stderr');
+      test.equals(result.code, 123);
+      test.equals(String(result), 'stderr');
+      test.done();
+    });
+  },
+  'non-zero exit code, fallback': function(test) {
+    test.expect(6);
+    util.spawn({
+      cmd: process.execPath,
+      args: [ this.script, 123 ],
+      fallback: 'custom fallback'
+    }, function(err, result, code) {
+      test.equals(err, null);
+      test.equals(code, 123);
+      test.equals(result.stdout, 'stdout');
+      test.equals(result.stderr, 'stderr');
+      test.equals(result.code, 123);
+      test.equals(String(result), 'custom fallback');
+      test.done();
+    });
+  },
+  'cmd not found': function(test) {
+    test.expect(3);
+    util.spawn({
+      cmd: 'nodewtfmisspelled',
+    }, function(err, result, code) {
+      test.ok(err instanceof Error);
+      test.equals(code, 127);
+      test.equals(result.code, 127);
+      test.done();
+    });
+  },
+  'cmd not found, fallback': function(test) {
+    test.expect(4);
+    util.spawn({
+      cmd: 'nodewtfmisspelled',
+      fallback: 'use a fallback or good luck'
+    }, function(err, result, code) {
+      test.equals(err, null);
+      test.equals(code, 127);
+      test.equals(result.code, 127);
+      test.equals(String(result), 'use a fallback or good luck');
+      test.done();
+    });
+  },
+  'cmd not in path': function(test) {
+    test.expect(6);
+    var win32 = process.platform === 'win32';
+    util.spawn({
+      cmd: 'test\\fixtures\\exec' + (win32 ? '.cmd' : '.sh'),
+    }, function(err, result, code) {
+      test.equals(err, null);
+      test.equals(code, 0);
+      test.equals(result.stdout, 'done');
+      test.equals(result.stderr, '');
+      test.equals(result.code, 0);
+      test.equals(String(result), 'done');
+      test.done();
+    });
+  },
+  'cmd not in path (with cwd)': function(test) {
+    test.expect(6);
+    var win32 = process.platform === 'win32';
+    util.spawn({
+      cmd: './exec' + (win32 ? '.cmd' : '.sh'),
+      opts: {cwd: 'test/fixtures'},
+    }, function(err, result, code) {
+      test.equals(err, null);
+      test.equals(code, 0);
+      test.equals(result.stdout, 'done');
+      test.equals(result.stderr, '');
+      test.equals(result.code, 0);
+      test.equals(String(result), 'done');
+      test.done();
+    });
+  },
+  'grunt': function(test) {
+    test.expect(3);
+    util.spawn({
+      grunt: true,
+      args: [ '--gruntfile', 'test/fixtures/Gruntfile-print-text.js', 'print:foo' ],
+    }, function(err, result, code) {
+      test.equals(err, null);
+      test.equals(code, 0);
+      test.ok(/^OUTPUT: foo/m.test(result.stdout), 'stdout should contain output indicating the grunt task was run.');
+      test.done();
+    });
+  },
+  'grunt (with cwd)': function(test) {
+    test.expect(3);
+    util.spawn({
+      grunt: true,
+      args: [ '--gruntfile', 'Gruntfile-print-text.js', 'print:foo' ],
+      opts: {cwd: 'test/fixtures'},
+    }, function(err, result, code) {
+      test.equals(err, null);
+      test.equals(code, 0);
+      test.ok(/^OUTPUT: foo/m.test(result.stdout), 'stdout should contain output indicating the grunt task was run.');
+      test.done();
+    });
+  },
+  'grunt passes execArgv': function(test) {
+    test.expect(3);
+    util.spawn({
+      cmd: process.execPath,
+      args: [ '--harmony', process.argv[1], '--gruntfile', 'test/fixtures/Gruntfile-execArgv.js'],
+    }, function(err, result, code) {
+      test.equals(err, null);
+      test.equals(code, 0);
+      test.ok(/^OUTPUT: --harmony/m.test(result.stdout), 'stdout should contain passed-through process.execArgv.');
+      test.done();
+    });
+  },
+  'grunt result.toString() with error': function(test) {
+    // grunt.log.error uses standard out, to be fixed in 0.5.
+    test.expect(4);
+    util.spawn({
+      grunt: true,
+      args: [ 'nonexistentTask' ]
+    }, function(err, result, code) {
+      test.ok(err instanceof Error, 'Should be an Error.');
+      test.equal(err.name, 'Error', 'Should be an Error.');
+      test.equals(code, 3);
+      test.ok(/Warning: Task "nonexistentTask" not found./m.test(result.toString()), 'stdout should contain output indicating the grunt task was (attempted to be) run.');
+      test.done();
+    });
+  },
+  'custom stdio stream(s)': function(test) {
+    test.expect(6);
+    var stdoutFile = new Tempfile();
+    var stderrFile = new Tempfile();
+    var stdout = fs.openSync(stdoutFile.path, 'a');
+    var stderr = fs.openSync(stderrFile.path, 'a');
+    var child = util.spawn({
+      cmd: process.execPath,
+      args: [ this.script, 0 ],
+      opts: {stdio: [null, stdout, stderr]},
+    }, function(err, result, code) {
+      test.equals(code, 0);
+      test.equals(String(fs.readFileSync(stdoutFile.path)), 'stdout\n', 'Child process stdout should have been captured via custom stream.');
+      test.equals(String(fs.readFileSync(stderrFile.path)), 'stderr\n', 'Child process stderr should have been captured via custom stream.');
+      stdoutFile.unlinkSync();
+      stderrFile.unlinkSync();
+      test.equals(result.stdout, '', 'Nothing will be passed to the stdout string when spawn stdio is a custom stream.');
+      test.done();
+    });
+    test.ok(!child.stdout, 'child should not have a stdout property.');
+    test.ok(!child.stderr, 'child should not have a stderr property.');
+  },
+};
+
+exports['util.spawn.multibyte'] = {
+  setUp: function(done) {
+    this.script = path.resolve('test/fixtures/spawn-multibyte.js');
+    done();
+  },
+  'partial stdout': function(test) {
+    test.expect(4);
+    util.spawn({
+      cmd: process.execPath,
+      args: [ this.script ],
+    }, function(err, result, code) {
+      test.equals(err, null);
+      test.equals(code, 0);
+      test.equals(result.stdout, 'ããã«ã¡ã¯');
+      test.equals(result.stderr, 'ããã«ã¡ã¯');
+      test.done();
+    });
+  }
+};
+
+exports['util.underscore.string'] = function(test) {
+  test.expect(4);
+  test.equals(util._.trim('    foo     '), 'foo', 'Should have trimmed the string.');
+  test.equals(util._.capitalize('foo'), 'Foo', 'Should have capitalized the first letter.');
+  test.equals(util._.words('one two three').length, 3, 'Should have counted three words.');
+  test.ok(util._.isBlank(' '), 'Should be blank.');
+  test.done();
+};
Index: Dev/trunk/node_modules/grunt/node_modules/iconv-lite/package.json
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/iconv-lite/package.json	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/iconv-lite/package.json	(revision 516)
@@ -77,8 +77,4 @@
   },
   "_id": "iconv-lite@0.2.11",
-  "dist": {
-    "shasum": "1827821f46962889765690b557c045f5cc3976eb"
-  },
-  "_from": "iconv-lite@~0.2.11",
-  "_resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz"
+  "_from": "iconv-lite@~0.2.11"
 }
Index: Dev/trunk/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/package.json
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/package.json	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/package.json	(revision 516)
@@ -70,8 +70,4 @@
   "readmeFilename": "README.markdown",
   "_id": "underscore.string@2.3.3",
-  "dist": {
-    "shasum": "a7cea3b9aa84d24cf1363ccbddd02ee10abee0c0"
-  },
-  "_from": "underscore.string@~2.3.1",
-  "_resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz"
+  "_from": "underscore.string@~2.3.1"
 }
Index: Dev/trunk/node_modules/grunt/node_modules/minimatch/.npmignore
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/minimatch/.npmignore	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/minimatch/.npmignore	(revision 516)
@@ -0,0 +1,1 @@
+node_modules
Index: Dev/trunk/node_modules/grunt/node_modules/minimatch/README.md
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/minimatch/README.md	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/minimatch/README.md	(revision 516)
@@ -20,4 +20,5 @@
 minimatch("bar.foo", "*.foo") // true!
 minimatch("bar.foo", "*.bar") // false!
+minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy!
 ```
 
@@ -36,42 +37,4 @@
 * `man 3 fnmatch`
 * `man 5 gitignore`
-
-### Comparisons to other fnmatch/glob implementations
-
-While strict compliance with the existing standards is a worthwhile
-goal, some discrepancies exist between minimatch and other
-implementations, and are intentional.
-
-If the pattern starts with a `!` character, then it is negated.  Set the
-`nonegate` flag to suppress this behavior, and treat leading `!`
-characters normally.  This is perhaps relevant if you wish to start the
-pattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`
-characters at the start of a pattern will negate the pattern multiple
-times.
-
-If a pattern starts with `#`, then it is treated as a comment, and
-will not match anything.  Use `\#` to match a literal `#` at the
-start of a line, or set the `nocomment` flag to suppress this behavior.
-
-The double-star character `**` is supported by default, unless the
-`noglobstar` flag is set.  This is supported in the manner of bsdglob
-and bash 4.1, where `**` only has special significance if it is the only
-thing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but
-`a/**b` will not.  **Note that this is different from the way that `**` is
-handled by ruby's `Dir` class.**
-
-If an escaped pattern has no matches, and the `nonull` flag is set,
-then minimatch.match returns the pattern as-provided, rather than
-interpreting the character escapes.  For example,
-`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
-`"*a?"`.  This is akin to setting the `nullglob` option in bash, except
-that it does not resolve escaped pattern characters.
-
-If brace expansion is not disabled, then it is performed before any
-other interpretation of the glob pattern.  Thus, a pattern like
-`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
-**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
-checked for validity.  Since those two are valid, matching proceeds.
-
 
 ## Minimatch Class
@@ -217,2 +180,39 @@
 Returns from negate expressions the same as if they were not negated.
 (Ie, true on a hit, false on a miss.)
+
+
+## Comparisons to other fnmatch/glob implementations
+
+While strict compliance with the existing standards is a worthwhile
+goal, some discrepancies exist between minimatch and other
+implementations, and are intentional.
+
+If the pattern starts with a `!` character, then it is negated.  Set the
+`nonegate` flag to suppress this behavior, and treat leading `!`
+characters normally.  This is perhaps relevant if you wish to start the
+pattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`
+characters at the start of a pattern will negate the pattern multiple
+times.
+
+If a pattern starts with `#`, then it is treated as a comment, and
+will not match anything.  Use `\#` to match a literal `#` at the
+start of a line, or set the `nocomment` flag to suppress this behavior.
+
+The double-star character `**` is supported by default, unless the
+`noglobstar` flag is set.  This is supported in the manner of bsdglob
+and bash 4.1, where `**` only has special significance if it is the only
+thing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but
+`a/**b` will not.
+
+If an escaped pattern has no matches, and the `nonull` flag is set,
+then minimatch.match returns the pattern as-provided, rather than
+interpreting the character escapes.  For example,
+`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
+`"*a?"`.  This is akin to setting the `nullglob` option in bash, except
+that it does not resolve escaped pattern characters.
+
+If brace expansion is not disabled, then it is performed before any
+other interpretation of the glob pattern.  Thus, a pattern like
+`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
+**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
+checked for validity.  Since those two are valid, matching proceeds.
Index: Dev/trunk/node_modules/grunt/node_modules/minimatch/minimatch.js
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/minimatch/minimatch.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/minimatch/minimatch.js	(revision 516)
@@ -69,15 +69,4 @@
 var slashSplit = /\/+/
 
-minimatch.monkeyPatch = monkeyPatch
-function monkeyPatch () {
-  var desc = Object.getOwnPropertyDescriptor(String.prototype, "match")
-  var orig = desc.value
-  desc.value = function (p) {
-    if (p instanceof Minimatch) return p.match(this)
-    return orig.call(this, p)
-  }
-  Object.defineProperty(String.prototype, desc)
-}
-
 minimatch.filter = filter
 function filter (pattern, options) {
@@ -179,4 +168,6 @@
 }
 
+Minimatch.prototype.debug = function() {}
+
 Minimatch.prototype.make = make
 function make () {
@@ -203,5 +194,7 @@
   var set = this.globSet = this.braceExpand()
 
-  if (options.debug) console.error(this.pattern, set)
+  if (options.debug) this.debug = console.error
+
+  this.debug(this.pattern, set)
 
   // step 3: now we have a set, so turn each one into a series of path-portion
@@ -214,5 +207,5 @@
   })
 
-  if (options.debug) console.error(this.pattern, set)
+  this.debug(this.pattern, set)
 
   // glob --> regexps
@@ -221,5 +214,5 @@
   }, this)
 
-  if (options.debug) console.error(this.pattern, set)
+  this.debug(this.pattern, set)
 
   // filter out everything that didn't compile properly.
@@ -228,5 +221,5 @@
   })
 
-  if (options.debug) console.error(this.pattern, set)
+  this.debug(this.pattern, set)
 
   this.set = set
@@ -303,9 +296,9 @@
   // and then prepend it to everything we find.
   if (pattern.charAt(0) !== "{") {
-    // console.error(pattern)
+    this.debug(pattern)
     var prefix = null
     for (var i = 0, l = pattern.length; i < l; i ++) {
       var c = pattern.charAt(i)
-      // console.error(i, c)
+      this.debug(i, c)
       if (c === "\\") {
         escaping = !escaping
@@ -318,9 +311,9 @@
     // actually no sets, all { were escaped.
     if (prefix === null) {
-      // console.error("no sets")
+      this.debug("no sets")
       return [pattern]
     }
 
-    var tail = braceExpand(pattern.substr(i), options)
+   var tail = braceExpand.call(this, pattern.substr(i), options)
     return tail.map(function (t) {
       return prefix + t
@@ -337,6 +330,6 @@
   var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
   if (numset) {
-    // console.error("numset", numset[1], numset[2])
-    var suf = braceExpand(pattern.substr(numset[0].length), options)
+    this.debug("numset", numset[1], numset[2])
+    var suf = braceExpand.call(this, pattern.substr(numset[0].length), options)
       , start = +numset[1]
       , end = +numset[2]
@@ -370,8 +363,8 @@
   }
 
-  // console.error("Entering for")
+  this.debug("Entering for")
   FOR: for (i = 1, l = pattern.length; i < l; i ++) {
     var c = pattern.charAt(i)
-    // console.error("", i, c)
+    this.debug("", i, c)
 
     if (escaping) {
@@ -421,20 +414,20 @@
   // and need to escape the leading brace
   if (depth !== 0) {
-    // console.error("didn't close", pattern)
-    return braceExpand("\\" + pattern, options)
+    this.debug("didn't close", pattern)
+    return braceExpand.call(this, "\\" + pattern, options)
   }
 
   // x{y,z} -> ["xy", "xz"]
-  // console.error("set", set)
-  // console.error("suffix", pattern.substr(i))
-  var suf = braceExpand(pattern.substr(i), options)
+  this.debug("set", set)
+  this.debug("suffix", pattern.substr(i))
+  var suf = braceExpand.call(this, pattern.substr(i), options)
   // ["b", "c{d,e}","{f,g}h"] ->
   //   [["b"], ["cd", "ce"], ["fh", "gh"]]
   var addBraces = set.length === 1
-  // console.error("set pre-expanded", set)
+  this.debug("set pre-expanded", set)
   set = set.map(function (p) {
-    return braceExpand(p, options)
-  })
-  // console.error("set expanded", set)
+    return braceExpand.call(this, p, options)
+  }, this)
+  this.debug("set expanded", set)
 
 
@@ -497,4 +490,5 @@
       : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
       : "(?!\\.)"
+    , self = this
 
   function clearStateChar () {
@@ -515,4 +509,5 @@
           break
       }
+      self.debug('clearStateChar %j %j', stateChar, re)
       stateChar = false
     }
@@ -523,7 +518,5 @@
       ; i ++ ) {
 
-    if (options.debug) {
-      console.error("%s\t%s %s %j", pattern, i, re, c)
-    }
+    this.debug("%s\t%s %s %j", pattern, i, re, c)
 
     // skip over any that are escaped.
@@ -552,11 +545,10 @@
       case "@":
       case "!":
-        if (options.debug) {
-          console.error("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
-        }
+        this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
 
         // all of those are literals inside a class, except that
         // the glob [!a] means [^a] in regexp
         if (inClass) {
+          this.debug('  in class')
           if (c === "!" && i === classStart + 1) c = "^"
           re += c
@@ -567,4 +559,5 @@
         // that there was something like ** or +? in there.
         // Handle the stateChar, then proceed with this one.
+        self.debug('call clearStateChar %j', stateChar)
         clearStateChar()
         stateChar = c
@@ -592,4 +585,5 @@
         // negation is (?:(?!js)[^/]*)
         re += stateChar === "!" ? "(?:(?!" : "(?:"
+        this.debug('plType %j %j', stateChar, re)
         stateChar = false
         continue
@@ -601,4 +595,5 @@
         }
 
+        clearStateChar()
         hasMagic = true
         re += ")"
@@ -624,4 +619,5 @@
         }
 
+        clearStateChar()
         re += "|"
         continue
@@ -716,5 +712,5 @@
     })
 
-    // console.error("tail=%j\n   %s", tail, tail)
+    this.debug("tail=%j\n   %s", tail, tail)
     var t = pl.type === "*" ? star
           : pl.type === "?" ? qmark
@@ -830,5 +826,5 @@
 Minimatch.prototype.match = match
 function match (f, partial) {
-  // console.error("match", f, this.pattern)
+  this.debug("match", f, this.pattern)
   // short-circuit in the case of busted things.
   // comments, etc.
@@ -848,7 +844,5 @@
   // treat the test path as a set of pathparts.
   f = f.split(slashSplit)
-  if (options.debug) {
-    console.error(this.pattern, "split", f)
-  }
+  this.debug(this.pattern, "split", f)
 
   // just ONE of the pattern sets in this.set needs to match
@@ -858,9 +852,14 @@
 
   var set = this.set
-  // console.error(this.pattern, "set", set)
+  this.debug(this.pattern, "set", set)
+
+  var splitFile = path.basename(f.join("/")).split("/")
 
   for (var i = 0, l = set.length; i < l; i ++) {
-    var pattern = set[i]
-    var hit = this.matchOne(f, pattern, partial)
+    var pattern = set[i], file = f
+    if (options.matchBase && pattern.length === 1) {
+      file = splitFile
+    }
+    var hit = this.matchOne(file, pattern, partial)
     if (hit) {
       if (options.flipNegate) return true
@@ -883,18 +882,10 @@
   var options = this.options
 
-  if (options.debug) {
-    console.error("matchOne",
-                  { "this": this
-                  , file: file
-                  , pattern: pattern })
-  }
-
-  if (options.matchBase && pattern.length === 1) {
-    file = path.basename(file.join("/")).split("/")
-  }
-
-  if (options.debug) {
-    console.error("matchOne", file.length, pattern.length)
-  }
+  this.debug("matchOne",
+              { "this": this
+              , file: file
+              , pattern: pattern })
+
+  this.debug("matchOne", file.length, pattern.length)
 
   for ( var fi = 0
@@ -905,13 +896,9 @@
       ; fi ++, pi ++ ) {
 
-    if (options.debug) {
-      console.error("matchOne loop")
-    }
+    this.debug("matchOne loop")
     var p = pattern[pi]
       , f = file[fi]
 
-    if (options.debug) {
-      console.error(pattern, p, f)
-    }
+    this.debug(pattern, p, f)
 
     // should be impossible.
@@ -920,6 +907,5 @@
 
     if (p === GLOBSTAR) {
-      if (options.debug)
-        console.error('GLOBSTAR', [pattern, p, f])
+      this.debug('GLOBSTAR', [pattern, p, f])
 
       // "**"
@@ -948,6 +934,5 @@
         , pr = pi + 1
       if (pr === pl) {
-        if (options.debug)
-          console.error('** at the end')
+        this.debug('** at the end')
         // a ** at the end will just swallow the rest.
         // We have found a match.
@@ -967,13 +952,10 @@
         var swallowee = file[fr]
 
-        if (options.debug) {
-          console.error('\nglobstar while',
-                        file, fr, pattern, pr, swallowee)
-        }
+        this.debug('\nglobstar while',
+                    file, fr, pattern, pr, swallowee)
 
         // XXX remove this slice.  Just pass the start index.
         if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
-          if (options.debug)
-            console.error('globstar found match!', fr, fl, swallowee)
+          this.debug('globstar found match!', fr, fl, swallowee)
           // found a match.
           return true
@@ -983,12 +965,10 @@
           if (swallowee === "." || swallowee === ".." ||
               (!options.dot && swallowee.charAt(0) === ".")) {
-            if (options.debug)
-              console.error("dot detected!", file, fr, pattern, pr)
+            this.debug("dot detected!", file, fr, pattern, pr)
             break WHILE
           }
 
           // ** swallows a segment, and continue.
-          if (options.debug)
-            console.error('globstar swallow a segment, and continue')
+          this.debug('globstar swallow a segment, and continue')
           fr ++
         }
@@ -999,5 +979,5 @@
       if (partial) {
         // ran out of file
-        // console.error("\n>>> no match, partial?", file, fr, pattern, pr)
+        this.debug("\n>>> no match, partial?", file, fr, pattern, pr)
         if (fr === fl) return true
       }
@@ -1015,12 +995,8 @@
         hit = f === p
       }
-      if (options.debug) {
-        console.error("string match", p, f, hit)
-      }
+      this.debug("string match", p, f, hit)
     } else {
       hit = f.match(p)
-      if (options.debug) {
-        console.error("pattern match", p, f, hit)
-      }
+      this.debug("pattern match", p, f, hit)
     }
 
Index: Dev/trunk/node_modules/grunt/node_modules/minimatch/node_modules/lru-cache/package.json
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/minimatch/node_modules/lru-cache/package.json	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/minimatch/node_modules/lru-cache/package.json	(revision 516)
@@ -30,8 +30,4 @@
   "homepage": "https://github.com/isaacs/node-lru-cache",
   "_id": "lru-cache@2.5.0",
-  "dist": {
-    "shasum": "be07d09e5b05f10b83d0cf01d4891a7729288c69"
-  },
-  "_from": "lru-cache@2",
-  "_resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz"
+  "_from": "lru-cache@2"
 }
Index: Dev/trunk/node_modules/grunt/node_modules/minimatch/package.json
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/minimatch/package.json	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/minimatch/package.json	(revision 516)
@@ -7,5 +7,5 @@
   "name": "minimatch",
   "description": "a glob matcher in javascript",
-  "version": "0.2.12",
+  "version": "0.2.14",
   "repository": {
     "type": "git",
@@ -14,5 +14,5 @@
   "main": "minimatch.js",
   "scripts": {
-    "test": "tap test"
+    "test": "tap test/*.js"
   },
   "engines": {
@@ -30,5 +30,5 @@
     "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE"
   },
-  "readme": "# minimatch\n\nA minimal matching utility.\n\n[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch)\n\n\nThis is the matching library used internally by npm.\n\nEventually, it will replace the C binding in node-glob.\n\nIt works by converting glob expressions into JavaScript `RegExp`\nobjects.\n\n## Usage\n\n```javascript\nvar minimatch = require(\"minimatch\")\n\nminimatch(\"bar.foo\", \"*.foo\") // true!\nminimatch(\"bar.foo\", \"*.bar\") // false!\n```\n\n## Features\n\nSupports these glob features:\n\n* Brace Expansion\n* Extended glob matching\n* \"Globstar\" `**` matching\n\nSee:\n\n* `man sh`\n* `man bash`\n* `man 3 fnmatch`\n* `man 5 gitignore`\n\n### Comparisons to other fnmatch/glob implementations\n\nWhile strict compliance with the existing standards is a worthwhile\ngoal, some discrepancies exist between minimatch and other\nimplementations, and are intentional.\n\nIf the pattern starts with a `!` character, then it is negated.  Set the\n`nonegate` flag to suppress this behavior, and treat leading `!`\ncharacters normally.  This is perhaps relevant if you wish to start the\npattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`\ncharacters at the start of a pattern will negate the pattern multiple\ntimes.\n\nIf a pattern starts with `#`, then it is treated as a comment, and\nwill not match anything.  Use `\\#` to match a literal `#` at the\nstart of a line, or set the `nocomment` flag to suppress this behavior.\n\nThe double-star character `**` is supported by default, unless the\n`noglobstar` flag is set.  This is supported in the manner of bsdglob\nand bash 4.1, where `**` only has special significance if it is the only\nthing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but\n`a/**b` will not.  **Note that this is different from the way that `**` is\nhandled by ruby's `Dir` class.**\n\nIf an escaped pattern has no matches, and the `nonull` flag is set,\nthen minimatch.match returns the pattern as-provided, rather than\ninterpreting the character escapes.  For example,\n`minimatch.match([], \"\\\\*a\\\\?\")` will return `\"\\\\*a\\\\?\"` rather than\n`\"*a?\"`.  This is akin to setting the `nullglob` option in bash, except\nthat it does not resolve escaped pattern characters.\n\nIf brace expansion is not disabled, then it is performed before any\nother interpretation of the glob pattern.  Thus, a pattern like\n`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded\n**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are\nchecked for validity.  Since those two are valid, matching proceeds.\n\n\n## Minimatch Class\n\nCreate a minimatch object by instanting the `minimatch.Minimatch` class.\n\n```javascript\nvar Minimatch = require(\"minimatch\").Minimatch\nvar mm = new Minimatch(pattern, options)\n```\n\n### Properties\n\n* `pattern` The original pattern the minimatch object represents.\n* `options` The options supplied to the constructor.\n* `set` A 2-dimensional array of regexp or string expressions.\n  Each row in the\n  array corresponds to a brace-expanded pattern.  Each item in the row\n  corresponds to a single path-part.  For example, the pattern\n  `{a,b/c}/d` would expand to a set of patterns like:\n\n        [ [ a, d ]\n        , [ b, c, d ] ]\n\n    If a portion of the pattern doesn't have any \"magic\" in it\n    (that is, it's something like `\"foo\"` rather than `fo*o?`), then it\n    will be left as a string rather than converted to a regular\n    expression.\n\n* `regexp` Created by the `makeRe` method.  A single regular expression\n  expressing the entire pattern.  This is useful in cases where you wish\n  to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.\n* `negate` True if the pattern is negated.\n* `comment` True if the pattern is a comment.\n* `empty` True if the pattern is `\"\"`.\n\n### Methods\n\n* `makeRe` Generate the `regexp` member if necessary, and return it.\n  Will return `false` if the pattern is invalid.\n* `match(fname)` Return true if the filename matches the pattern, or\n  false otherwise.\n* `matchOne(fileArray, patternArray, partial)` Take a `/`-split\n  filename, and match it against a single row in the `regExpSet`.  This\n  method is mainly for internal use, but is exposed so that it can be\n  used by a glob-walker that needs to avoid excessive filesystem calls.\n\nAll other methods are internal, and will be called as necessary.\n\n## Functions\n\nThe top-level exported function has a `cache` property, which is an LRU\ncache set to store 100 items.  So, calling these methods repeatedly\nwith the same pattern and options will use the same Minimatch object,\nsaving the cost of parsing it multiple times.\n\n### minimatch(path, pattern, options)\n\nMain export.  Tests a path against the pattern using the options.\n\n```javascript\nvar isJS = minimatch(file, \"*.js\", { matchBase: true })\n```\n\n### minimatch.filter(pattern, options)\n\nReturns a function that tests its\nsupplied argument, suitable for use with `Array.filter`.  Example:\n\n```javascript\nvar javascripts = fileList.filter(minimatch.filter(\"*.js\", {matchBase: true}))\n```\n\n### minimatch.match(list, pattern, options)\n\nMatch against the list of\nfiles, in the style of fnmatch or glob.  If nothing is matched, and\noptions.nonull is set, then return a list containing the pattern itself.\n\n```javascript\nvar javascripts = minimatch.match(fileList, \"*.js\", {matchBase: true}))\n```\n\n### minimatch.makeRe(pattern, options)\n\nMake a regular expression object from the pattern.\n\n## Options\n\nAll options are `false` by default.\n\n### debug\n\nDump a ton of stuff to stderr.\n\n### nobrace\n\nDo not expand `{a,b}` and `{1..3}` brace sets.\n\n### noglobstar\n\nDisable `**` matching against multiple folder names.\n\n### dot\n\nAllow patterns to match filenames starting with a period, even if\nthe pattern does not explicitly have a period in that spot.\n\nNote that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`\nis set.\n\n### noext\n\nDisable \"extglob\" style patterns like `+(a|b)`.\n\n### nocase\n\nPerform a case-insensitive match.\n\n### nonull\n\nWhen a match is not found by `minimatch.match`, return a list containing\nthe pattern itself.  When set, an empty list is returned if there are\nno matches.\n\n### matchBase\n\nIf set, then patterns without slashes will be matched\nagainst the basename of the path if it contains slashes.  For example,\n`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.\n\n### nocomment\n\nSuppress the behavior of treating `#` at the start of a pattern as a\ncomment.\n\n### nonegate\n\nSuppress the behavior of treating a leading `!` character as negation.\n\n### flipNegate\n\nReturns from negate expressions the same as if they were not negated.\n(Ie, true on a hit, false on a miss.)\n",
+  "readme": "# minimatch\n\nA minimal matching utility.\n\n[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch)\n\n\nThis is the matching library used internally by npm.\n\nEventually, it will replace the C binding in node-glob.\n\nIt works by converting glob expressions into JavaScript `RegExp`\nobjects.\n\n## Usage\n\n```javascript\nvar minimatch = require(\"minimatch\")\n\nminimatch(\"bar.foo\", \"*.foo\") // true!\nminimatch(\"bar.foo\", \"*.bar\") // false!\nminimatch(\"bar.foo\", \"*.+(bar|foo)\", { debug: true }) // true, and noisy!\n```\n\n## Features\n\nSupports these glob features:\n\n* Brace Expansion\n* Extended glob matching\n* \"Globstar\" `**` matching\n\nSee:\n\n* `man sh`\n* `man bash`\n* `man 3 fnmatch`\n* `man 5 gitignore`\n\n## Minimatch Class\n\nCreate a minimatch object by instanting the `minimatch.Minimatch` class.\n\n```javascript\nvar Minimatch = require(\"minimatch\").Minimatch\nvar mm = new Minimatch(pattern, options)\n```\n\n### Properties\n\n* `pattern` The original pattern the minimatch object represents.\n* `options` The options supplied to the constructor.\n* `set` A 2-dimensional array of regexp or string expressions.\n  Each row in the\n  array corresponds to a brace-expanded pattern.  Each item in the row\n  corresponds to a single path-part.  For example, the pattern\n  `{a,b/c}/d` would expand to a set of patterns like:\n\n        [ [ a, d ]\n        , [ b, c, d ] ]\n\n    If a portion of the pattern doesn't have any \"magic\" in it\n    (that is, it's something like `\"foo\"` rather than `fo*o?`), then it\n    will be left as a string rather than converted to a regular\n    expression.\n\n* `regexp` Created by the `makeRe` method.  A single regular expression\n  expressing the entire pattern.  This is useful in cases where you wish\n  to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.\n* `negate` True if the pattern is negated.\n* `comment` True if the pattern is a comment.\n* `empty` True if the pattern is `\"\"`.\n\n### Methods\n\n* `makeRe` Generate the `regexp` member if necessary, and return it.\n  Will return `false` if the pattern is invalid.\n* `match(fname)` Return true if the filename matches the pattern, or\n  false otherwise.\n* `matchOne(fileArray, patternArray, partial)` Take a `/`-split\n  filename, and match it against a single row in the `regExpSet`.  This\n  method is mainly for internal use, but is exposed so that it can be\n  used by a glob-walker that needs to avoid excessive filesystem calls.\n\nAll other methods are internal, and will be called as necessary.\n\n## Functions\n\nThe top-level exported function has a `cache` property, which is an LRU\ncache set to store 100 items.  So, calling these methods repeatedly\nwith the same pattern and options will use the same Minimatch object,\nsaving the cost of parsing it multiple times.\n\n### minimatch(path, pattern, options)\n\nMain export.  Tests a path against the pattern using the options.\n\n```javascript\nvar isJS = minimatch(file, \"*.js\", { matchBase: true })\n```\n\n### minimatch.filter(pattern, options)\n\nReturns a function that tests its\nsupplied argument, suitable for use with `Array.filter`.  Example:\n\n```javascript\nvar javascripts = fileList.filter(minimatch.filter(\"*.js\", {matchBase: true}))\n```\n\n### minimatch.match(list, pattern, options)\n\nMatch against the list of\nfiles, in the style of fnmatch or glob.  If nothing is matched, and\noptions.nonull is set, then return a list containing the pattern itself.\n\n```javascript\nvar javascripts = minimatch.match(fileList, \"*.js\", {matchBase: true}))\n```\n\n### minimatch.makeRe(pattern, options)\n\nMake a regular expression object from the pattern.\n\n## Options\n\nAll options are `false` by default.\n\n### debug\n\nDump a ton of stuff to stderr.\n\n### nobrace\n\nDo not expand `{a,b}` and `{1..3}` brace sets.\n\n### noglobstar\n\nDisable `**` matching against multiple folder names.\n\n### dot\n\nAllow patterns to match filenames starting with a period, even if\nthe pattern does not explicitly have a period in that spot.\n\nNote that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`\nis set.\n\n### noext\n\nDisable \"extglob\" style patterns like `+(a|b)`.\n\n### nocase\n\nPerform a case-insensitive match.\n\n### nonull\n\nWhen a match is not found by `minimatch.match`, return a list containing\nthe pattern itself.  When set, an empty list is returned if there are\nno matches.\n\n### matchBase\n\nIf set, then patterns without slashes will be matched\nagainst the basename of the path if it contains slashes.  For example,\n`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.\n\n### nocomment\n\nSuppress the behavior of treating `#` at the start of a pattern as a\ncomment.\n\n### nonegate\n\nSuppress the behavior of treating a leading `!` character as negation.\n\n### flipNegate\n\nReturns from negate expressions the same as if they were not negated.\n(Ie, true on a hit, false on a miss.)\n\n\n## Comparisons to other fnmatch/glob implementations\n\nWhile strict compliance with the existing standards is a worthwhile\ngoal, some discrepancies exist between minimatch and other\nimplementations, and are intentional.\n\nIf the pattern starts with a `!` character, then it is negated.  Set the\n`nonegate` flag to suppress this behavior, and treat leading `!`\ncharacters normally.  This is perhaps relevant if you wish to start the\npattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`\ncharacters at the start of a pattern will negate the pattern multiple\ntimes.\n\nIf a pattern starts with `#`, then it is treated as a comment, and\nwill not match anything.  Use `\\#` to match a literal `#` at the\nstart of a line, or set the `nocomment` flag to suppress this behavior.\n\nThe double-star character `**` is supported by default, unless the\n`noglobstar` flag is set.  This is supported in the manner of bsdglob\nand bash 4.1, where `**` only has special significance if it is the only\nthing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but\n`a/**b` will not.\n\nIf an escaped pattern has no matches, and the `nonull` flag is set,\nthen minimatch.match returns the pattern as-provided, rather than\ninterpreting the character escapes.  For example,\n`minimatch.match([], \"\\\\*a\\\\?\")` will return `\"\\\\*a\\\\?\"` rather than\n`\"*a?\"`.  This is akin to setting the `nullglob` option in bash, except\nthat it does not resolve escaped pattern characters.\n\nIf brace expansion is not disabled, then it is performed before any\nother interpretation of the glob pattern.  Thus, a pattern like\n`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded\n**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are\nchecked for validity.  Since those two are valid, matching proceeds.\n",
   "readmeFilename": "README.md",
   "bugs": {
@@ -36,5 +36,5 @@
   },
   "homepage": "https://github.com/isaacs/minimatch",
-  "_id": "minimatch@0.2.12",
-  "_from": "minimatch@0.x.x"
+  "_id": "minimatch@0.2.14",
+  "_from": "minimatch@~0.2.12"
 }
Index: Dev/trunk/node_modules/grunt/node_modules/minimatch/test/extglob-ending-with-state-char.js
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/minimatch/test/extglob-ending-with-state-char.js	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/minimatch/test/extglob-ending-with-state-char.js	(revision 516)
@@ -0,0 +1,8 @@
+var test = require('tap').test
+var minimatch = require('../')
+
+test('extglob ending with statechar', function(t) {
+  t.notOk(minimatch('ax', 'a?(b*)'))
+  t.ok(minimatch('ax', '?(a*|b)'))
+  t.end()
+})
Index: Dev/trunk/node_modules/grunt/node_modules/rimraf/README.md
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/rimraf/README.md	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/rimraf/README.md	(revision 516)
@@ -1,3 +1,3 @@
-A `rm -rf` for node.
+`rm -rf` for node.
 
 Install with `npm install rimraf`, or just drop rimraf.js somewhere.
@@ -10,9 +10,8 @@
 errors are handled for you:
 
-* `EBUSY` -  rimraf will back off a maximum of opts.maxBusyTries times
-  before giving up.
-* `EMFILE` - If too many file descriptors get opened, rimraf will
-  patiently wait until more become available.
-
+* Windows: `EBUSY` and `ENOTEMPTY` - rimraf will back off a maximum of
+  `opts.maxBusyTries` times before giving up.
+* `ENOENT` - If the file doesn't exist, rimraf will return
+  successfully, since your desired outcome is already the case.
 
 ## rimraf.sync
@@ -20,2 +19,12 @@
 It can remove stuff synchronously, too.  But that's not so good.  Use
 the async API.  It's better.
+
+## CLI
+
+If installed with `npm install rimraf -g` it can be used as a global
+command `rimraf <path>` which is useful for cross platform support.
+
+## mkdirp
+
+If you need to create a directory recursively, check out
+[mkdirp](https://github.com/substack/node-mkdirp).
Index: Dev/trunk/node_modules/grunt/node_modules/rimraf/bin.js
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/rimraf/bin.js	(revision 516)
+++ Dev/trunk/node_modules/grunt/node_modules/rimraf/bin.js	(revision 516)
@@ -0,0 +1,33 @@
+#!/usr/bin/env node
+
+var rimraf = require('./')
+
+var help = false
+var dashdash = false
+var args = process.argv.slice(2).filter(function(arg) {
+  if (dashdash)
+    return !!arg
+  else if (arg === '--')
+    dashdash = true
+  else if (arg.match(/^(-+|\/)(h(elp)?|\?)$/))
+    help = true
+  else
+    return !!arg
+});
+
+if (help || args.length === 0) {
+  // If they didn't ask for help, then this is not a "success"
+  var log = help ? console.log : console.error
+  log('Usage: rimraf <path>')
+  log('')
+  log('  Deletes all files and folders at "path" recursively.')
+  log('')
+  log('Options:')
+  log('')
+  log('  -h, --help    Display this usage info')
+  process.exit(help ? 0 : 1)
+} else {
+  args.forEach(function(arg) {
+    rimraf.sync(arg)
+  })
+}
Index: Dev/trunk/node_modules/grunt/node_modules/rimraf/package.json
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/rimraf/package.json	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/rimraf/package.json	(revision 516)
@@ -1,5 +1,5 @@
 {
   "name": "rimraf",
-  "version": "2.0.3",
+  "version": "2.2.6",
   "main": "rimraf.js",
   "description": "A deep deletion module for node (like `rm -rf`)",
@@ -13,7 +13,4 @@
     "url": "https://github.com/isaacs/rimraf/raw/master/LICENSE"
   },
-  "optionalDependencies": {
-    "graceful-fs": "~1.1"
-  },
   "repository": {
     "type": "git",
@@ -22,4 +19,7 @@
   "scripts": {
     "test": "cd test && bash run.sh"
+  },
+  "bin": {
+    "rimraf": "./bin.js"
   },
   "contributors": [
@@ -46,5 +46,5 @@
     }
   ],
-  "readme": "A `rm -rf` for node.\n\nInstall with `npm install rimraf`, or just drop rimraf.js somewhere.\n\n## API\n\n`rimraf(f, callback)`\n\nThe callback will be called with an error if there is one.  Certain\nerrors are handled for you:\n\n* `EBUSY` -  rimraf will back off a maximum of opts.maxBusyTries times\n  before giving up.\n* `EMFILE` - If too many file descriptors get opened, rimraf will\n  patiently wait until more become available.\n\n\n## rimraf.sync\n\nIt can remove stuff synchronously, too.  But that's not so good.  Use\nthe async API.  It's better.\n",
+  "readme": "`rm -rf` for node.\n\nInstall with `npm install rimraf`, or just drop rimraf.js somewhere.\n\n## API\n\n`rimraf(f, callback)`\n\nThe callback will be called with an error if there is one.  Certain\nerrors are handled for you:\n\n* Windows: `EBUSY` and `ENOTEMPTY` - rimraf will back off a maximum of\n  `opts.maxBusyTries` times before giving up.\n* `ENOENT` - If the file doesn't exist, rimraf will return\n  successfully, since your desired outcome is already the case.\n\n## rimraf.sync\n\nIt can remove stuff synchronously, too.  But that's not so good.  Use\nthe async API.  It's better.\n\n## CLI\n\nIf installed with `npm install rimraf -g` it can be used as a global\ncommand `rimraf <path>` which is useful for cross platform support.\n\n## mkdirp\n\nIf you need to create a directory recursively, check out\n[mkdirp](https://github.com/substack/node-mkdirp).\n",
   "readmeFilename": "README.md",
   "bugs": {
@@ -52,8 +52,9 @@
   },
   "homepage": "https://github.com/isaacs/rimraf",
-  "dependencies": {
-    "graceful-fs": "~1.1"
+  "_id": "rimraf@2.2.6",
+  "dist": {
+    "shasum": "c28d4de4cafcd392b82d02729509c65e3502240c"
   },
-  "_id": "rimraf@2.0.3",
-  "_from": "rimraf@~2.0.3"
+  "_from": "rimraf@~2.2.6",
+  "_resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.6.tgz"
 }
Index: Dev/trunk/node_modules/grunt/node_modules/rimraf/rimraf.js
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/rimraf/rimraf.js	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/rimraf/rimraf.js	(revision 516)
@@ -3,23 +3,5 @@
 
 var path = require("path")
-  , fs
-
-try {
-  // optional dependency
-  fs = require("graceful-fs")
-} catch (er) {
-  fs = require("fs")
-}
-
-var lstat = "lstat"
-if (process.platform === "win32") {
-  // not reliable on windows prior to 0.7.9
-  var v = process.version.replace(/^v/, '').split(/\.|-/).map(Number)
-  if (v[0] === 0 && (v[1] < 7 || v[1] == 7 && v[2] < 9)) {
-    lstat = "stat"
-  }
-}
-if (!fs[lstat]) lstat = "stat"
-var lstatSync = lstat + "Sync"
+var fs = require("fs")
 
 // for EMFILE handling
@@ -28,13 +10,14 @@
 exports.BUSYTRIES_MAX = 3
 
+var isWindows = (process.platform === "win32")
+
 function rimraf (p, cb) {
-
   if (!cb) throw new Error("No callback passed to rimraf()")
 
   var busyTries = 0
-
   rimraf_(p, function CB (er) {
     if (er) {
-      if (er.code === "EBUSY" && busyTries < exports.BUSYTRIES_MAX) {
+      if (isWindows && (er.code === "EBUSY" || er.code === "ENOTEMPTY") &&
+          busyTries < exports.BUSYTRIES_MAX) {
         busyTries ++
         var time = busyTries * 100
@@ -61,98 +44,132 @@
 }
 
+// Two possible strategies.
+// 1. Assume it's a file.  unlink it, then do the dir stuff on EPERM or EISDIR
+// 2. Assume it's a directory.  readdir, then do the file stuff on ENOTDIR
+//
+// Both result in an extra syscall when you guess wrong.  However, there
+// are likely far more normal files in the world than directories.  This
+// is based on the assumption that a the average number of files per
+// directory is >= 1.
+//
+// If anyone ever complains about this, then I guess the strategy could
+// be made configurable somehow.  But until then, YAGNI.
 function rimraf_ (p, cb) {
-  fs[lstat](p, function (er, s) {
+  fs.unlink(p, function (er) {
     if (er) {
-      // already gone
-      if (er.code === "ENOENT") return cb()
-      // some other kind of error, permissions, etc.
-      return cb(er)
+      if (er.code === "ENOENT")
+        return cb(null)
+      if (er.code === "EPERM")
+        return (isWindows) ? fixWinEPERM(p, er, cb) : rmdir(p, er, cb)
+      if (er.code === "EISDIR")
+        return rmdir(p, er, cb)
     }
-
-    return rm_(p, s, false, cb)
+    return cb(er)
   })
 }
 
-
-var myGid = function myGid () {
-  var g = process.getgid && process.getgid()
-  myGid = function myGid () { return g }
-  return g
+function fixWinEPERM (p, er, cb) {
+  fs.chmod(p, 666, function (er2) {
+    if (er2)
+      cb(er2.code === "ENOENT" ? null : er)
+    else
+      fs.stat(p, function(er3, stats) {
+        if (er3)
+          cb(er3.code === "ENOENT" ? null : er)
+        else if (stats.isDirectory())
+          rmdir(p, er, cb)
+        else
+          fs.unlink(p, cb)
+      })
+  })
 }
 
-var myUid = function myUid () {
-  var u = process.getuid && process.getuid()
-  myUid = function myUid () { return u }
-  return u
+function fixWinEPERMSync (p, er, cb) {
+  try {
+    fs.chmodSync(p, 666)
+  } catch (er2) {
+    if (er2.code !== "ENOENT")
+      throw er
+  }
+
+  try {
+    var stats = fs.statSync(p)
+  } catch (er3) {
+    if (er3 !== "ENOENT")
+      throw er
+  }
+
+  if (stats.isDirectory())
+    rmdirSync(p, er)
+  else
+    fs.unlinkSync(p)
 }
 
-
-function writable (s) {
-  var mode = s.mode || 0777
-    , uid = myUid()
-    , gid = myGid()
-  return (mode & 0002)
-      || (gid === s.gid && (mode & 0020))
-      || (uid === s.uid && (mode & 0200))
+function rmdir (p, originalEr, cb) {
+  // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS)
+  // if we guessed wrong, and it's not a directory, then
+  // raise the original error.
+  fs.rmdir(p, function (er) {
+    if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM"))
+      rmkids(p, cb)
+    else if (er && er.code === "ENOTDIR")
+      cb(originalEr)
+    else
+      cb(er)
+  })
 }
 
-function rm_ (p, s, didWritableCheck, cb) {
-  if (!didWritableCheck && !writable(s)) {
-    // make file writable
-    // user/group/world, doesn't matter at this point
-    // since it's about to get nuked.
-    return fs.chmod(p, s.mode | 0222, function (er) {
-      if (er) return cb(er)
-      rm_(p, s, true, cb)
-    })
-  }
-
-  if (!s.isDirectory()) {
-    return fs.unlink(p, cb)
-  }
-
-  // directory
+function rmkids(p, cb) {
   fs.readdir(p, function (er, files) {
-    if (er) return cb(er)
-    asyncForEach(files.map(function (f) {
-      return path.join(p, f)
-    }), function (file, cb) {
-      rimraf(file, cb)
-    }, function (er) {
-      if (er) return cb(er)
-      fs.rmdir(p, cb)
+    if (er)
+      return cb(er)
+    var n = files.length
+    if (n === 0)
+      return fs.rmdir(p, cb)
+    var errState
+    files.forEach(function (f) {
+      rimraf(path.join(p, f), function (er) {
+        if (errState)
+          return
+        if (er)
+          return cb(errState = er)
+        if (--n === 0)
+          fs.rmdir(p, cb)
+      })
     })
   })
 }
 
-function asyncForEach (list, fn, cb) {
-  if (!list.length) cb()
-  var c = list.length
-    , errState = null
-  list.forEach(function (item, i, list) {
-    fn(item, function (er) {
-      if (errState) return
-      if (er) return cb(errState = er)
-      if (-- c === 0) return cb()
-    })
-  })
+// this looks simpler, and is strictly *faster*, but will
+// tie up the JavaScript thread and fail on excessively
+// deep directory trees.
+function rimrafSync (p) {
+  try {
+    fs.unlinkSync(p)
+  } catch (er) {
+    if (er.code === "ENOENT")
+      return
+    if (er.code === "EPERM")
+      return isWindows ? fixWinEPERMSync(p, er) : rmdirSync(p, er)
+    if (er.code !== "EISDIR")
+      throw er
+    rmdirSync(p, er)
+  }
 }
 
-// this looks simpler, but it will fail with big directory trees,
-// or on slow stupid awful cygwin filesystems
-function rimrafSync (p) {
+function rmdirSync (p, originalEr) {
   try {
-    var s = fs[lstatSync](p)
+    fs.rmdirSync(p)
   } catch (er) {
-    if (er.code === "ENOENT") return
-    throw er
+    if (er.code === "ENOENT")
+      return
+    if (er.code === "ENOTDIR")
+      throw originalEr
+    if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")
+      rmkidsSync(p)
   }
+}
 
-  if (!writable(s)) {
-    fs.chmodSync(p, s.mode | 0222)
-  }
-
-  if (!s.isDirectory()) return fs.unlinkSync(p)
-
+function rmkidsSync (p) {
   fs.readdirSync(p).forEach(function (f) {
     rimrafSync(path.join(p, f))
Index: Dev/trunk/node_modules/grunt/node_modules/underscore.string/package.json
===================================================================
--- Dev/trunk/node_modules/grunt/node_modules/underscore.string/package.json	(revision 484)
+++ Dev/trunk/node_modules/grunt/node_modules/underscore.string/package.json	(revision 516)
@@ -69,8 +69,4 @@
   "readmeFilename": "README.markdown",
   "_id": "underscore.string@2.2.1",
-  "dist": {
-    "shasum": "2aa155e7c49bcbfd88ec69b8c9694d885385c717"
-  },
-  "_from": "underscore.string@~2.2.1",
-  "_resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz"
+  "_from": "underscore.string@~2.2.1"
 }
Index: Dev/trunk/node_modules/grunt/package.json
===================================================================
--- Dev/trunk/node_modules/grunt/package.json	(revision 484)
+++ Dev/trunk/node_modules/grunt/package.json	(revision 516)
@@ -2,5 +2,5 @@
   "name": "grunt",
   "description": "The JavaScript Task Runner",
-  "version": "0.4.2",
+  "version": "0.4.4",
   "author": {
     "name": "\"Cowboy\" Ben Alman",
@@ -59,5 +59,5 @@
     "minimatch": "~0.2.12",
     "nopt": "~1.0.10",
-    "rimraf": "~2.0.3",
+    "rimraf": "~2.2.6",
     "lodash": "~0.9.2",
     "underscore.string": "~2.2.1",
@@ -65,5 +65,6 @@
     "js-yaml": "~2.0.5",
     "exit": "~0.1.1",
-    "getobject": "~0.1.0"
+    "getobject": "~0.1.0",
+    "grunt-legacy-util": "~0.1.2"
   },
   "devDependencies": {
@@ -76,11 +77,11 @@
     "shelljs": "~0.2.5"
   },
-  "readme": "# Grunt: The JavaScript Task Runner [![Build Status](https://secure.travis-ci.org/gruntjs/grunt.png?branch=master)](http://travis-ci.org/gruntjs/grunt)\n\n<img align=\"right\" height=\"260\" src=\"http://gruntjs.com/img/grunt-logo-no-wordmark.svg\">\n\n\n### Documentation\n\nVisit the [gruntjs.com](http://gruntjs.com/) website for all the things.\n\n### Support / Contributing\nBefore you make an issue, please read our [Contributing](http://gruntjs.com/contributing) guide.\n\nYou can find the grunt team in [#grunt on irc.freenode.net](http://webchat.freenode.net/?channels=grunt).\n\n### Release History\nSee the [CHANGELOG](CHANGELOG).\n",
+  "readme": "# Grunt: The JavaScript Task Runner\n\n[![Build Status](https://secure.travis-ci.org/gruntjs/grunt.png?branch=master)](http://travis-ci.org/gruntjs/grunt)\n[![Built with Grunt](https://cdn.gruntjs.com/builtwith.png)](http://gruntjs.com/)\n\n<img align=\"right\" height=\"260\" src=\"http://gruntjs.com/img/grunt-logo-no-wordmark.svg\">\n\n\n### Documentation\n\nVisit the [gruntjs.com](http://gruntjs.com/) website for all the things.\n\n### Support / Contributing\nBefore you make an issue, please read our [Contributing](http://gruntjs.com/contributing) guide.\n\nYou can find the grunt team in [#grunt on irc.freenode.net](http://webchat.freenode.net/?channels=grunt).\n\n### Release History\nSee the [CHANGELOG](CHANGELOG).\n",
   "readmeFilename": "README.md",
-  "_id": "grunt@0.4.2",
+  "_id": "grunt@0.4.4",
   "dist": {
-    "shasum": "1f6804f00e977dd90b9f97b1faed480215db0857"
+    "shasum": "64f477fef801475ab92f1819a691c6c71b72902e"
   },
-  "_from": "grunt@0.4.2",
-  "_resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.2.tgz"
+  "_from": "grunt@0.4.4",
+  "_resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.4.tgz"
 }
