var util = require("util");
var os = require("os");

var now = new Date().toISOString();

function shallowCopy(obj) {
	var result = {};
	Object.keys(obj).forEach(function(key) {
		result[key] = obj[key];
	});
	return result;
}

module.exports = function(grunt) {

	// Windows cmd does not accept paths with / and unix shell does not accept paths with \\ and we need to execute from a sub-dir.
	// To circumvent the issue, hack our environment's PATH and let the OS deal with it, which in practice works
	process.env.path = process.env.path + (os.platform() === "win32" ? ";" : ":") + "node_modules/.bin";

	grunt.initConfig({
		deploymentEnvironment: process.env["DeploymentEnvironment"] || "local",
		resourceDownloadEnvironment: process.env["ResourceDownloadEnvironment"] || "local",
		jobName: process.env["JOB_NAME"] || "local",
		buildNumber: process.env["BUILD_NUMBER"] || "non-ci",
		dateString: now.substr(0, now.indexOf("T")),

		pkg: grunt.file.readJSON("package.json"),

		ts: {
			options: {
				target: 'es5',
				module: 'commonjs',
				sourceMap: true,
				declaration: false,
				removeComments: false,
				noImplicitAny: true
			},

			devlib: {
				src: ["lib/**/*.ts"],
				reference: "lib/.d.ts"
			},

			devall: {
				src: ["lib/**/*.ts", "test/**/*.ts"],
				reference: "lib/.d.ts"
			},

			release_build: {
				src: ["lib/**/*.ts", "test/**/*.ts"],
				reference: "lib/.d.ts",
				options: {
					sourceMap: false,
					removeComments: true
				}
			}
		},

		watch: {
			devall: {
				files: ["lib/**/*.ts", 'test/**/*.ts'],
				tasks: ['ts:devall'],
				options: {
					atBegin: true,
					interrupt: true
				}
			}
		},

		shell: {
			options: {
				stdout: true,
				stderr: true
			},

			prepare_resources: {
				command: "node bin/appbuilder.js dev-prepackage"
			},

			ci_unit_tests: {
				command: "npm test",
				options: {
					execOptions: {
						env: (function() {
							var env = shallowCopy(process.env);
							env["XUNIT_FILE"] = "test-reports.xml";
							env["LOG_XUNIT"] = "true";
							return env;
						})()
					}
				}
			},

			apply_deployment_environment: {
				command: "node bin/appbuilder.js dev-config-apply <%= deploymentEnvironment %>"
			},

			build_package: {
				command: "npm pack",
				options: {
					execOptions: {
						env: (function() {
							var env = shallowCopy(process.env);
							env["APPBUILDER_SKIP_POSTINSTALL_TASKS"] = "1";
							return env;
						})()
					}
				}
			}
		},

		clean: {
			src: ["test/**/*.js*", "lib/**/*.js*", "!lib/common/vendor/*.js", "!lib/hooks/**/*.js", "!lib/common/hooks/**/*.js", "*.tgz"]
		}
	});

	grunt.loadNpmTasks("grunt-contrib-clean");
	grunt.loadNpmTasks("grunt-contrib-watch");
	grunt.loadNpmTasks("grunt-shell");
	grunt.loadNpmTasks("grunt-ts");

	grunt.registerTask("set_package_version", function(version) {
		var fs = require("fs");
		var buildVersion = version !== undefined ? version : process.env["BUILD_NUMBER"];
		if (process.env["BUILD_CAUSE_GHPRBCAUSE"]) {
			buildVersion = "PR" + buildVersion;
		}

		var packageJson = grunt.file.readJSON("package.json");
		var versionParts = packageJson.version.split("-");
		versionParts[1] = buildVersion;
		packageJson.version = versionParts.join("-");
		grunt.file.write("package.json", JSON.stringify(packageJson, null, "  "));
	});

	grunt.registerTask("test", ["ts:devall", "shell:npm_test"]);
	grunt.registerTask("pack", [
		"ts:release_build",
		"shell:apply_deployment_environment",
		"shell:prepare_resources",

		"shell:ci_unit_tests",

		"set_package_version",
		"shell:build_package"
	]);

	grunt.registerTask("default", "ts:devlib");
};

@@ -599,16 +599,50 @@
 .bin%22;%0A%0A
+%09var defaultEnvironment = %22sit%22;%0A%0A
 %09grunt.i
@@ -714,31 +714,42 @@
 onment%22%5D %7C%7C 
-%22local%22
+defaultEnvironment
 ,%0A%09%09resource
@@ -811,31 +811,42 @@
 onment%22%5D %7C%7C 
-%22local%22
+defaultEnvironment
 ,%0A%09%09jobName:
@@ -877,15 +877,26 @@
  %7C%7C 
-%22local%22
+defaultEnvironment
 ,%0A%09%09
@@ -1777,16 +1777,150 @@
 %0A%09%09%09%7D,%0A%0A
+%09%09%09apply_resources_environment: %7B%0A%09%09%09%09command: %22node bin/appbuilder.js dev-config-apply %3C%25= resourceDownloadEnvironment %25%3E%22%0A%09%09%09%7D,%0A%09%09%09%0A
 %09%09%09prepa
@@ -3618,16 +3618,17 @@
 build%22,%0A
+%0A
 %09%09%22shell
@@ -3630,34 +3630,33 @@
 shell:apply_
-deployment
+resources
 _environment
@@ -3683,24 +3683,64 @@
 resources%22,%0A
+%09%09%22shell:apply_deployment_environment%22, 
 %0A%09%09%22shell:ci

Fix gruntfile