diff --git a/esprima-to-ast.js b/esprima-to-ast.js
index 0c2a0a384ed0be35ce7b7f920eb02123211cc651..e86aaf8bca7157a1b97dab3f066cef025c927f27 100644
--- a/esprima-to-ast.js
+++ b/esprima-to-ast.js
@@ -3,6 +3,9 @@
 //https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API$revision/707671
 
 function esprimaToAST(prog, sourceText) {
+
+  var contextStrictMode = false;
+
   var toList = function (array) {
     var r = {type: "list", tag: "[]"};
     for (var i = array.length - 1; i >= 0; i--) {
@@ -37,6 +40,29 @@ function esprimaToAST(prog, sourceText) {
     return toOption(funcTr, (arr.length > 0 ? arr[0] : null));
   }
 
+  var isDirectivePrologue = function(stat) {
+    return stat.type === "ExpressionStatement" &&
+           stat.expression.type === "Literal" &&
+           (typeof stat.expression.value) === "string";
+  }
+
+  var isUseStrictDirective = function(stat) {
+    return isDirectivePrologue(stat) &&
+           /^["']use strict["']$/.test(stat.expression.raw);
+  }
+
+  var getDirectivePrologue = function(statArr) {
+    // statArr.takeWhile(isDirectivePrologue)
+    return statArr.filter(function(stat) {
+      this.ok = this.ok && isDirectivePrologue(stat);
+      return this.ok;
+    }, { ok: true });
+  };
+
+  var bodyIsStrict = function(statArr) {
+    return getDirectivePrologue(statArr).some(isUseStrictDirective);
+  }
+
   /*** Miscellaneous Helper Nodes ***/
 
   // The JSCert AST special-cases this instance of option
@@ -60,8 +86,7 @@ function esprimaToAST(prog, sourceText) {
     };
     var r = {loc: toLoc(prog.loc), type: "prog"};
     r.tag = "Coq_prog_intro";
-    // TODO deal with strictness
-    r.strictness = false;
+    r.strictness = contextStrictMode = bodyIsStrict(prog.body);
     r.elements = toList(prog.body.map(trStatAsElement));
     return r;
   };
@@ -92,16 +117,20 @@ function esprimaToAST(prog, sourceText) {
       }
 
       var loc = toLoc(stat.loc);
+      var prog = { loc: loc, type: "prog", tag: "Coq_prog_intro" };
+
+      var oldContextStrictMode = contextStrictMode;
+      contextStrictMode = contextStrictMode || bodyIsStrict(stat.body);
+      prog.strictness = contextStrictMode;
+      prog.elements = toList(stat.body.map(trStatAsElement));
+      contextStrictMode = oldContextStrictMode;
+
       var source = "";
       if (sourceText && stat.range) {
         // Esprima's range includes the { }
         source = sourceText.slice(stat.range[0]+1, stat.range[1]-1);
       }
 
-      // TODO strictness
-      var prog = {loc: loc, type: "prog", tag: "Coq_prog_intro",
-                  strictness: false,
-                  elements: toList(stat.body.map(trStatAsElement))};
       return {loc: loc, type: "funcbody", tag: "Coq_funcbody_intro",
                 prog: prog, source: source};
   };
diff --git a/generator/TODO b/generator/TODO
index cf9af5b7287b338783217b8d51bc45c0ae3067b9..b17dd0c8bb4f779692df71bff62568a7aa2f91d8 100644
--- a/generator/TODO
+++ b/generator/TODO
@@ -41,12 +41,6 @@ NEXT
 
 - in JsInterpreter let append = strappend (* hack for compatibility, to do cleanup *)
 
-[thomas, biggest piece, ask if anything problematic]
-- update the code that translates esprima syntax to recognize
-  "use strict" directives, which come as first statement of
-  a body, in hte form of a raw expression of raw type "use script".
-  (look on the web for code that already does this for esprima).
-
 [alan or thomas]
 - figure out what to do for Parser_syntax Parser_main
 
diff --git a/test/parser.js b/test/parser.js
index 11e69c2a3c0c3b050e7196081a4668434099f443..1d845420432598e400ae95402df05206a005ddf4 100644
--- a/test/parser.js
+++ b/test/parser.js
@@ -9,9 +9,6 @@ var assert = require('chai').assert;
 var esprima = require('esprima');
 var esprimaToAST = require('../esprima-to-ast.js');
 
-var test262path = fs.readlinkSync(__dirname + '/test262');
-var tests = [];
-
 /* Tests whether a given test is negative.
  * Returns: a string if type of failure specified, true, or false
  */
@@ -203,6 +200,78 @@ function typecheckAST(ast) {
   return typecheck("prog", ast);
 }
 
+describe("Custom testcases", function() {
+  it("Extracts function body strings", function() {
+    var source =
+`function f() {
+  // body line 1
+a()};`;
+
+    var prog = esprima.parse(source, {loc: true, range: true});
+    var ast = esprimaToAST.esprimaToAST(prog, source);
+
+    var sourceBody = /{([^]*)}/.exec(source)[1];
+    assert.strictEqual(sourceBody, ast.elements.head.body.source);
+
+  });
+
+  [ { source: `"use strict";`                 , strict: true }
+  , { source: `'use strict';`                 , strict: true }
+  , { source: `"not strict"; "use strict";`   , strict: true }
+  , { source: `""; 0; "use strict";`          , strict: false }
+  , { source: `"use\\u0020strict";`           , strict: false }
+  ].forEach(function (test) {
+    it("Correctly parses that `" + test.source + "` is " + (test.strict ? " " : "not ") + "strict mode code.", function() {
+      var est = esprima.parse(test.source, {loc: true, range: true});
+      var ast = esprimaToAST.esprimaToAST(est, test.source);
+      assert.strictEqual(test.strict, ast.strictness);
+    });
+  });
+
+  var isFunction = function(stat) {
+    return stat.tag === "Coq_element_func_decl"
+      || (stat.tag === "Coq_element_stat" &&
+          stat.stat.tag === "Coq_stat_expr" &&
+          stat.stat.expr.tag === "Coq_expr_function");
+  };
+
+
+  var getFunctionStrictness = function(stat) {
+    if (stat.tag === "Coq_element_func_decl") {
+      return stat.body.prog.strictness;
+    } else if (stat.tag === "Coq_element_stat") {
+      return stat.stat.expr.body.prog.strictness;
+    } else {
+      assert.fail();
+    }
+  };
+
+  [ { source: `"use strict"; function x() {}`                , strict: [true] }
+  , { source: `'use strict'; (function() {})`                , strict: [true] }
+  , { source: `function x() {"use strict";}`                 , strict: [true] }
+  , { source: `(function() {"use strict";})`                 , strict: [true] }
+  , { source: `(function(){}); function x(){"use strict";};` , strict: [false, true] }
+  ].forEach(function (test) {
+    it("Correctly parses that `" + test.source + "` is " + (test.strict ? " " : "not ") + "strict mode code.", function() {
+      var est = esprima.parse(test.source, {loc: true, range: true});
+      var ast = esprimaToAST.esprimaToAST(est, test.source);
+
+      var listElem = ast.elements;
+      var index = 0;
+      while (listElem.tag === "::") {
+        if (isFunction(listElem.head)) {
+          assert.strictEqual(test.strict[index], getFunctionStrictness(listElem.head));
+          index++;
+        }
+        listElem = listElem.tail;
+      }
+    });
+  });
+});
+
+var test262path = fs.readlinkSync(__dirname + '/test262');
+var tests = [];
+
 walk(test262path)
 .pipe(filter.obj(file => file.stats.isFile() && file.path.endsWith(".js")))
 .on('readable', function() {
@@ -257,19 +326,3 @@ walk(test262path)
 
   run();
 });
-
-describe("Custom testcases", function() {
-  it("Extracts function body strings", function() {
-    var source =
-`function f() {
-  // body line 1
-a()};`;
-
-    var prog = esprima.parse(source, {loc: true, range: true});
-    var ast = esprimaToAST.esprimaToAST(prog, source);
-
-    var sourceBody = /{([^]*)}/.exec(source)[1];
-    assert.strictEqual(sourceBody, ast.elements.head.body.source);
-
-  });
-});