diff --git a/.eslintrc b/.eslintrc
index 237b5ee6d..8cd3bd6fe 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -40,7 +40,7 @@
     "no-dupe-keys": 2,
     "no-duplicate-case": 2,
     "no-empty": 2,
-    "no-empty-class": 2,
+    "no-empty-character-class": 2,
     "no-ex-assign": 2,
     "no-extra-boolean-cast": 2,
     "no-extra-parens": 0,
@@ -55,7 +55,7 @@
     "no-negated-in-lhs": 2,
     "no-obj-calls": 2,
     "no-regex-spaces": 2,
-    "no-reserved-keys": 2,    // Important for IE
+    "quote-props": [2, "as-needed", {"keywords": true}],
     "no-sparse-arrays": 0,
 
     // Optimizer and coverage will handle/highlight this and can be useful for debugging
@@ -175,7 +175,7 @@
     "no-ternary": 0,
     "no-trailing-spaces": 2,
     "no-underscore-dangle": 0,
-    "no-wrap-func": 2,
+    "no-extra-parens": [2, "functions"],
     "one-var": 0,
     "operator-assignment": 0,
     "padded-blocks": 0,
@@ -192,7 +192,7 @@
     "space-infix-ops": 2,
     "space-return-throw-case": 2,
     "space-unary-ops": 2,
-    "spaced-line-comment": 2,
+    "spaced-comment": [2, "always", {"markers": [","]}],
     "wrap-regex": 1,
 
     "no-var": 1
diff --git a/Gruntfile.js b/Gruntfile.js
index 2850a9052..3bb1c1661 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -1,4 +1,4 @@
-/*eslint-disable no-process-env */
+/* eslint-disable no-process-env */
 module.exports = function(grunt) {
 
   grunt.initConfig({
diff --git a/bench/throughput.js b/bench/throughput.js
index 9f1f79858..e8ea5d910 100644
--- a/bench/throughput.js
+++ b/bench/throughput.js
@@ -1,7 +1,7 @@
 var _ = require('underscore'),
     runner = require('./util/template-runner'),
 
-    eco, dust, Handlebars, Mustache, eco;
+    eco, dust, Handlebars, Mustache;
 
 try {
   dust = require('dustjs-linkedin');
diff --git a/components/bower.json b/components/bower.json
index fce893b41..cb17eb32d 100644
--- a/components/bower.json
+++ b/components/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "handlebars",
-  "version": "4.0.0",
+  "version": "4.0.1",
   "main": "handlebars.js",
   "license": "MIT",
   "dependencies": {}
diff --git a/components/handlebars.js.nuspec b/components/handlebars.js.nuspec
index b259400bd..ee1fce077 100644
--- a/components/handlebars.js.nuspec
+++ b/components/handlebars.js.nuspec
@@ -2,7 +2,7 @@
 <package>
 	<metadata>
 		<id>handlebars.js</id>
-		<version>4.0.0</version>
+		<version>4.0.1</version>
 		<authors>handlebars.js Authors</authors>
 		<licenseUrl>https://github.com/wycats/handlebars.js/blob/master/LICENSE</licenseUrl>
 		<projectUrl>https://github.com/wycats/handlebars.js/</projectUrl>
diff --git a/lib/handlebars/base.js b/lib/handlebars/base.js
index e68031ee6..087874a5d 100644
--- a/lib/handlebars/base.js
+++ b/lib/handlebars/base.js
@@ -4,7 +4,7 @@ import {registerDefaultHelpers} from './helpers';
 import {registerDefaultDecorators} from './decorators';
 import logger from './logger';
 
-export const VERSION = '4.0.0';
+export const VERSION = '4.0.1';
 export const COMPILER_REVISION = 7;
 
 export const REVISION_CHANGES = {
diff --git a/lib/handlebars/compiler/code-gen.js b/lib/handlebars/compiler/code-gen.js
index 6541fe873..5ec052f77 100644
--- a/lib/handlebars/compiler/code-gen.js
+++ b/lib/handlebars/compiler/code-gen.js
@@ -1,4 +1,4 @@
-/*global define */
+/* global define */
 import {isArray} from '../utils';
 
 let SourceNode;
diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js
index ede0b5e49..d0f206c58 100644
--- a/lib/handlebars/compiler/javascript-compiler.js
+++ b/lib/handlebars/compiler/javascript-compiler.js
@@ -471,7 +471,7 @@ JavaScriptCompiler.prototype = {
 
     let len = parts.length;
     for (; i < len; i++) {
-      /*eslint-disable no-loop-func */
+      /* eslint-disable no-loop-func */
       this.replaceStack((current) => {
         let lookup = this.nameLookup(current, parts[i], type);
         // We want to ensure that zero and false are handled properly if the context (falsy flag)
@@ -483,7 +483,7 @@ JavaScriptCompiler.prototype = {
           return [' && ', lookup];
         }
       });
-      /*eslint-enable no-loop-func */
+      /* eslint-enable no-loop-func */
     }
   },
 
@@ -703,6 +703,7 @@ JavaScriptCompiler.prototype = {
     }
     options.helpers = 'helpers';
     options.partials = 'partials';
+    options.decorators = 'container.decorators';
 
     if (!isDynamic) {
       params.unshift(this.nameLookup('partials', name, 'partial'));
diff --git a/lib/handlebars/compiler/printer.js b/lib/handlebars/compiler/printer.js
index 66e7c7d4b..6ad43baec 100644
--- a/lib/handlebars/compiler/printer.js
+++ b/lib/handlebars/compiler/printer.js
@@ -1,4 +1,4 @@
-/*eslint-disable new-cap */
+/* eslint-disable new-cap */
 import Visitor from './visitor';
 
 export function print(ast) {
@@ -168,4 +168,4 @@ PrintVisitor.prototype.Hash = function(hash) {
 PrintVisitor.prototype.HashPair = function(pair) {
   return pair.key + '=' + this.accept(pair.value);
 };
-/*eslint-enable new-cap */
+/* eslint-enable new-cap */
diff --git a/lib/handlebars/no-conflict.js b/lib/handlebars/no-conflict.js
index a421f57e5..ad41e96fa 100644
--- a/lib/handlebars/no-conflict.js
+++ b/lib/handlebars/no-conflict.js
@@ -1,4 +1,4 @@
-/*global window */
+/* global window */
 export default function(Handlebars) {
   /* istanbul ignore next */
   let root = typeof global !== 'undefined' ? global : window,
diff --git a/lib/handlebars/utils.js b/lib/handlebars/utils.js
index d34646b7d..1cf7e3219 100644
--- a/lib/handlebars/utils.js
+++ b/lib/handlebars/utils.js
@@ -31,7 +31,7 @@ export let toString = Object.prototype.toString;
 
 // Sourced from lodash
 // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
-/*eslint-disable func-style */
+/* eslint-disable func-style */
 let isFunction = function(value) {
   return typeof value === 'function';
 };
@@ -43,7 +43,7 @@ if (isFunction(/x/)) {
   };
 }
 export {isFunction};
-/*eslint-enable func-style */
+/* eslint-enable func-style */
 
 /* istanbul ignore next */
 export const isArray = Array.isArray || function(value) {
diff --git a/lib/precompiler.js b/lib/precompiler.js
index 9f23ef661..a20d1419d 100644
--- a/lib/precompiler.js
+++ b/lib/precompiler.js
@@ -1,4 +1,4 @@
-/*eslint-disable no-console */
+/* eslint-disable no-console */
 import Async from 'async';
 import fs from 'fs';
 import * as Handlebars from './handlebars';
diff --git a/package.json b/package.json
index 814e5277e..8752ea0e7 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "handlebars",
   "barename": "handlebars",
-  "version": "4.0.0",
+  "version": "4.0.1",
   "description": "Handlebars provides the power necessary to let you build semantic templates effectively with no frustration",
   "homepage": "http://www.handlebarsjs.com/",
   "keywords": [
@@ -23,14 +23,13 @@
   "dependencies": {
     "async": "^1.4.0",
     "optimist": "^0.6.1",
-    "source-map": "^0.1.40"
+    "source-map": "^0.4.4"
   },
   "optionalDependencies": {
     "uglify-js": "~2.4"
   },
   "devDependencies": {
-    "async": "^0.9.0",
-    "aws-sdk": "~1.5.0",
+    "aws-sdk": "^2.1.49",
     "babel-loader": "^5.0.0",
     "babel-runtime": "^5.1.10",
     "benchmark": "~1.0",
@@ -46,16 +45,15 @@
     "grunt-contrib-requirejs": "0.x",
     "grunt-contrib-uglify": "0.x",
     "grunt-contrib-watch": "0.x",
-    "grunt-eslint": "^11.0.0",
+    "grunt-eslint": "^17.1.0",
     "grunt-saucelabs": "8.x",
     "grunt-webpack": "^1.0.8",
     "istanbul": "^0.3.0",
     "jison": "~0.3.0",
-    "keen.io": "0.0.3",
     "mocha": "~1.20.0",
     "mock-stdin": "^0.3.0",
-    "mustache": "0.x",
-    "semver": "^4.0.0",
+    "mustache": "^2.1.3",
+    "semver": "^5.0.1",
     "underscore": "^1.5.1"
   },
   "main": "lib/index.js",
diff --git a/release-notes.md b/release-notes.md
index dba8a55ec..ef55b63e8 100644
--- a/release-notes.md
+++ b/release-notes.md
@@ -2,50 +2,12 @@
 
 ## Development
 
-[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.0...master)
+[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.1...master)
 
-## v4.0.0 - September 1st, 2015
-- [#1082](https://github.com/wycats/handlebars.js/pull/1082) - Decorators and Inline Partials ([@kpdecker](https://api.github.com/users/kpdecker))
-- [#1076](https://github.com/wycats/handlebars.js/pull/1076) - Implement partial blocks ([@kpdecker](https://api.github.com/users/kpdecker))
-- [#1087](https://github.com/wycats/handlebars.js/pull/1087) - Fix #each when last object entry has empty key ([@denniskuczynski](https://api.github.com/users/denniskuczynski))
-- [#1084](https://github.com/wycats/handlebars.js/pull/1084) - Bump uglify version to fix vulnerability ([@John-Steidley](https://api.github.com/users/John-Steidley))
-- [#1068](https://github.com/wycats/handlebars.js/pull/1068) - Fix typo ([@0xack13](https://api.github.com/users/0xack13))
-- [#1060](https://github.com/wycats/handlebars.js/pull/1060) - #1056 Fixed grammar for nested raw blocks ([@ericbn](https://api.github.com/users/ericbn))
-- [#1052](https://github.com/wycats/handlebars.js/pull/1052) - Updated year in License ([@maqnouch](https://api.github.com/users/maqnouch))
-- [#1037](https://github.com/wycats/handlebars.js/pull/1037) - Fix minor typos in README ([@tomxtobin](https://api.github.com/users/tomxtobin))
-- [#1032](https://github.com/wycats/handlebars.js/issues/1032) - Is it possible to render a partial without the parent scope? ([@aputinski](https://api.github.com/users/aputinski))
-- [#1019](https://github.com/wycats/handlebars.js/pull/1019) - Fixes typo in tests ([@aymerick](https://api.github.com/users/aymerick))
-- [#1016](https://github.com/wycats/handlebars.js/issues/1016) - Version mis-match ([@mayankdedhia](https://api.github.com/users/mayankdedhia))
-- [#1023](https://github.com/wycats/handlebars.js/issues/1023) - is it possible for nested custom helpers to communicate between each other?
-- [#893](https://github.com/wycats/handlebars.js/issues/893) - [Proposal] Section blocks.
-- [#792](https://github.com/wycats/handlebars.js/issues/792) - feature request: inline partial definitions
-- [#583](https://github.com/wycats/handlebars.js/issues/583) - Parent path continues to drill down depth with multiple conditionals
-- [#404](https://github.com/wycats/handlebars.js/issues/404) - Add named child helpers that can be referenced by block helpers
-- Escape = in HTML content - [83b8e84](https://github.com/wycats/handlebars.js/commit/83b8e84)
-- Drop AST constructors in favor of JSON - [95d84ba](https://github.com/wycats/handlebars.js/commit/95d84ba)
-- Pass container rather than exec as context - [9a2d1d6](https://github.com/wycats/handlebars.js/commit/9a2d1d6)
-- Add ignoreStandalone compiler option - [ea3a5a1](https://github.com/wycats/handlebars.js/commit/ea3a5a1)
-- Ignore empty when iterating on sparse arrays - [06d515a](https://github.com/wycats/handlebars.js/commit/06d515a)
-- Add support for string and stdin precompilation - [0de8dac](https://github.com/wycats/handlebars.js/commit/0de8dac)
-- Simplify object assignment generation logic - [77e6bfc](https://github.com/wycats/handlebars.js/commit/77e6bfc)
-- Bulletproof AST.helpers.helperExpression - [93b0760](https://github.com/wycats/handlebars.js/commit/93b0760)
-- Always return string responses - [8e868ab](https://github.com/wycats/handlebars.js/commit/8e868ab)
-- Pass undefined fields to helpers in strict mode - [5d4b8da](https://github.com/wycats/handlebars.js/commit/5d4b8da)
-- Avoid depth creation when context remains the same - [279e038](https://github.com/wycats/handlebars.js/commit/279e038)
-- Improve logging API - [9a49d35](https://github.com/wycats/handlebars.js/commit/9a49d35)
-- Fix with operator in no @data mode - [231a8d7](https://github.com/wycats/handlebars.js/commit/231a8d7)
-- Allow empty key name in each iteration - [1bb640b](https://github.com/wycats/handlebars.js/commit/1bb640b)
-- Add with block parameter support - [2a85106](https://github.com/wycats/handlebars.js/commit/2a85106)
-- Fix escaping of non-javascript identifiers - [410141c](https://github.com/wycats/handlebars.js/commit/410141c)
-- Fix location information for programs - [93faffa](https://github.com/wycats/handlebars.js/commit/93faffa)
-
-Compatibility notes:
-- Depthed paths are now conditional pushed on to the stack. If the helper uses the same context, then a new stack is not created. This leads to behavior the better matches expectations for helpers like `if` that do not seem to alter the context. Any instances of `../` in templates will need to be checked for the correct behavior under 4.0.0. In general templates will either reduce the number of `../` instances or leave them as is. See [#1028](https://github.com/wycats/handlebars.js/issues/1028).
-- The `=` character is now HTML escaped. This closes a potential exploit case when using unquoted attributes, i.e. `<div foo={{bar}}>`. In general it's recommended that attributes always be quoted when their values are generated from a mustache to avoid any potential exploit surfaces.
-- AST constructors have been dropped in favor of plain old javascript objects
-- The runtime version has been increased. Precompiled templates will need to use runtime of at least 4.0.0.
+## v4.0.1 - September 2nd, 2015
+- Fix failure when using decorators in partials - 05b82a2
 
-[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.0...v4.0.0)
+[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.0...v4.0.1)
 
 ## v4.0.0 - September 1st, 2015
 - [#1082](https://github.com/wycats/handlebars.js/pull/1082) - Decorators and Inline Partials ([@kpdecker](https://api.github.com/users/kpdecker))
diff --git a/spec/basic.js b/spec/basic.js
index 8859545d9..e4b253665 100644
--- a/spec/basic.js
+++ b/spec/basic.js
@@ -61,14 +61,14 @@ describe('basic context', function() {
     shouldCompileTo('num: {{num1/num2}}', {num1: {num2: 0}}, 'num: 0');
   });
   it('false', function() {
-    /*eslint-disable no-new-wrappers */
+    /* eslint-disable no-new-wrappers */
     shouldCompileTo('val1: {{val1}}, val2: {{val2}}', {val1: false, val2: new Boolean(false)}, 'val1: false, val2: false');
     shouldCompileTo('val: {{.}}', false, 'val: false');
     shouldCompileTo('val: {{val1/val2}}', {val1: {val2: false}}, 'val: false');
 
     shouldCompileTo('val1: {{{val1}}}, val2: {{{val2}}}', {val1: false, val2: new Boolean(false)}, 'val1: false, val2: false');
     shouldCompileTo('val: {{{val1/val2}}}', {val1: {val2: false}}, 'val: false');
-    /*eslint-enable */
+    /* eslint-enable */
   });
 
   it('should handle undefined and null', function() {
diff --git a/spec/builtins.js b/spec/builtins.js
index f06a1ad23..dc1df0a3e 100644
--- a/spec/builtins.js
+++ b/spec/builtins.js
@@ -257,7 +257,7 @@ describe('builtin helpers', function() {
   });
 
   describe('#log', function() {
-    /*eslint-disable no-console */
+    /* eslint-disable no-console */
     if (typeof console === 'undefined') {
       return;
     }
@@ -408,7 +408,7 @@ describe('builtin helpers', function() {
       shouldCompileTo(string, hash, '');
       equals(true, called);
     });
-    /*eslint-enable no-console */
+    /* eslint-enable no-console */
   });
 
 
diff --git a/spec/env/browser.js b/spec/env/browser.js
index c9414d402..8049dda0e 100644
--- a/spec/env/browser.js
+++ b/spec/env/browser.js
@@ -19,12 +19,12 @@ global.CompilerContext = {
 };
 
 function safeEval(templateSpec) {
-  /*eslint-disable no-eval, no-console */
+  /* eslint-disable no-eval, no-console */
   try {
     return eval('(' + templateSpec + ')');
   } catch (err) {
     console.error(templateSpec);
     throw err;
   }
-  /*eslint-enable no-eval, no-console */
+  /* eslint-enable no-eval, no-console */
 }
diff --git a/spec/env/common.js b/spec/env/common.js
index 111294c68..2a24db20f 100644
--- a/spec/env/common.js
+++ b/spec/env/common.js
@@ -66,7 +66,7 @@ global.shouldThrow = function(callback, type, msg) {
       throw new AssertError('Type failure: ' + err);
     }
     if (msg && !(msg.test ? msg.test(err.message) : msg === err.message)) {
-      equal(msg, err.message);
+      throw new AssertError('Throw mismatch: Expected ' + err.message + ' to match ' + msg + '\n\n' + err.stack, shouldThrow);
     }
   }
   if (failed) {
diff --git a/spec/env/node.js b/spec/env/node.js
index 62d9fe9b6..881609d2e 100644
--- a/spec/env/node.js
+++ b/spec/env/node.js
@@ -13,12 +13,12 @@ global.CompilerContext = {
 };
 
 function safeEval(templateSpec) {
-  /*eslint-disable no-eval, no-console */
+  /* eslint-disable no-eval, no-console */
   try {
     return eval('(' + templateSpec + ')');
   } catch (err) {
     console.error(templateSpec);
     throw err;
   }
-  /*eslint-enable no-eval, no-console */
+  /* eslint-enable no-eval, no-console */
 }
diff --git a/spec/env/runner.js b/spec/env/runner.js
index 98d2482e8..4ff1e7e48 100644
--- a/spec/env/runner.js
+++ b/spec/env/runner.js
@@ -1,4 +1,4 @@
-/*eslint-disable no-console */
+/* eslint-disable no-console */
 var fs = require('fs'),
     Mocha = require('mocha'),
     path = require('path');
@@ -7,8 +7,6 @@ var errors = 0,
     testDir = path.dirname(__dirname),
     grep = process.argv[2];
 
-var files = [ testDir + '/basic.js' ];
-
 var files = fs.readdirSync(testDir)
       .filter(function(name) { return (/.*\.js$/).test(name); })
       .map(function(name) { return testDir + '/' + name; });
@@ -16,9 +14,9 @@ var files = fs.readdirSync(testDir)
 run('./runtime', function() {
   run('./browser', function() {
     run('./node', function() {
-      /*eslint-disable no-process-exit */
+      /* eslint-disable no-process-exit */
       process.exit(errors);
-      /*eslint-enable no-process-exit */
+      /* eslint-enable no-process-exit */
     });
   });
 });
diff --git a/spec/env/runtime.js b/spec/env/runtime.js
index a7b42f51e..9d1c04995 100644
--- a/spec/env/runtime.js
+++ b/spec/env/runtime.js
@@ -39,12 +39,12 @@ global.CompilerContext = {
 };
 
 function safeEval(templateSpec) {
-  /*eslint-disable no-eval, no-console */
+  /* eslint-disable no-eval, no-console */
   try {
     return eval('(' + templateSpec + ')');
   } catch (err) {
     console.error(templateSpec);
     throw err;
   }
-  /*eslint-enable no-eval, no-console */
+  /* eslint-enable no-eval, no-console */
 }
diff --git a/spec/javascript-compiler.js b/spec/javascript-compiler.js
index 28e698824..5a10388f0 100644
--- a/spec/javascript-compiler.js
+++ b/spec/javascript-compiler.js
@@ -16,9 +16,9 @@ describe('javascript-compiler api', function() {
       handlebarsEnv.JavaScriptCompiler.prototype.nameLookup = function(parent, name) {
         return parent + '.bar_' + name;
       };
-      /*eslint-disable camelcase */
+      /* eslint-disable camelcase */
       shouldCompileTo('{{foo}}', { bar_foo: 'food' }, 'food');
-      /*eslint-enable camelcase */
+      /* eslint-enable camelcase */
     });
 
     // Tests nameLookup dot vs. bracket behavior.  Bracket is required in certain cases
diff --git a/spec/precompiler.js b/spec/precompiler.js
index e1ad5ade9..f9759a9ce 100644
--- a/spec/precompiler.js
+++ b/spec/precompiler.js
@@ -1,4 +1,4 @@
-/*eslint-disable no-console */
+/* eslint-disable no-console */
 describe('precompiler', function() {
   // NOP Under non-node environments
   if (typeof process === 'undefined') {
diff --git a/spec/regressions.js b/spec/regressions.js
index e8942a484..ae0797e9a 100644
--- a/spec/regressions.js
+++ b/spec/regressions.js
@@ -103,13 +103,13 @@ describe('Regressions', function() {
   });
 
   it('GH-534: Object prototype aliases', function() {
-    /*eslint-disable no-extend-native */
+    /* eslint-disable no-extend-native */
     Object.prototype[0xD834] = true;
 
     shouldCompileTo('{{foo}}', { foo: 'bar' }, 'bar');
 
     delete Object.prototype[0xD834];
-    /*eslint-enable no-extend-native */
+    /* eslint-enable no-extend-native */
   });
 
   it('GH-437: Matching escaping', function() {
@@ -203,4 +203,13 @@ describe('Regressions', function() {
     array[3] = 'bar';
     shouldCompileTo('{{#each array}}{{@index}}{{.}}{{/each}}', {array: array}, '1foo3bar');
   });
+
+  it('should support multiple levels of inline partials', function() {
+    var string = '{{#> layout}}{{#*inline "subcontent"}}subcontent{{/inline}}{{/layout}}';
+    var partials = {
+      doctype: 'doctype{{> content}}',
+      layout: '{{#> doctype}}{{#*inline "content"}}layout{{> subcontent}}{{/inline}}{{/doctype}}'
+    };
+    shouldCompileToWithPartials(string, [{}, {}, partials], true, 'doctypelayoutsubcontent');
+  });
 });
diff --git a/spec/spec.js b/spec/spec.js
index ae1ec3805..221d32ec2 100644
--- a/spec/spec.js
+++ b/spec/spec.js
@@ -34,9 +34,9 @@ describe('spec', function() {
       var data = _.clone(test.data);
       if (data.lambda) {
         // Blergh
-        /*eslint-disable no-eval */
+        /* eslint-disable no-eval */
         data.lambda = eval('(' + data.lambda.js + ')');
-        /*eslint-enable no-eval */
+        /* eslint-enable no-eval */
       }
       it(name + ' - ' + test.name, function() {
         if (test.partials) {
diff --git a/tasks/metrics.js b/tasks/metrics.js
index 9044306cf..b04967dd0 100644
--- a/tasks/metrics.js
+++ b/tasks/metrics.js
@@ -1,25 +1,12 @@
 var _ = require('underscore'),
     async = require('async'),
-    git = require('./util/git'),
-    Keen = require('keen.io'),
     metrics = require('../bench');
 
 module.exports = function(grunt) {
   grunt.registerTask('metrics', function() {
     var done = this.async(),
         execName = grunt.option('name'),
-        events = {},
-
-        projectId = process.env.KEEN_PROJECTID,
-        writeKey = process.env.KEEN_WRITEKEY,
-        keen;
-
-    if (!execName && projectId && writeKey) {
-      keen = Keen.configure({
-        projectId: projectId,
-        writeKey: writeKey
-      });
-    }
+        events = {};
 
     async.each(_.keys(metrics), function(name, complete) {
         if (/^_/.test(name) || (execName && name !== execName)) {
@@ -31,33 +18,6 @@ module.exports = function(grunt) {
           complete();
         });
       },
-      function() {
-        if (!keen) {
-          return done();
-        }
-
-        emit(keen, events, function(err) {
-          if (err) {
-            throw err;
-          }
-
-          grunt.log.writeln('Metrics recorded.');
-          done();
-        });
-      });
+      done);
   });
 };
-function emit(keen, collections, callback) {
-  git.commitInfo(function(err, info) {
-    _.each(collections, function(collection) {
-      _.each(collection, function(event) {
-        if (info.tagName) {
-          event.tag = info.tagName;
-        }
-        event.sha = info.head;
-      });
-    });
-
-    keen.addEvents(collections, callback);
-  });
-}
diff --git a/tasks/test.js b/tasks/test.js
index 74473244a..7d6659b09 100644
--- a/tasks/test.js
+++ b/tasks/test.js
@@ -32,7 +32,7 @@ module.exports = function(grunt) {
   grunt.registerTask('test:cov', function() {
     var done = this.async();
 
-    var runner = childProcess.fork('node_modules/.bin/istanbul', ['cover', '--', './spec/env/runner.js'], {stdio: 'inherit'});
+    var runner = childProcess.fork('node_modules/.bin/istanbul', ['cover', '--source-map', '--', './spec/env/runner.js'], {stdio: 'inherit'});
     runner.on('close', function(code) {
       if (code != 0) {
         grunt.fatal(code + ' tests failed');
