From 7435491fabea298cefb3d0ee6398e34cda9f2818 Mon Sep 17 00:00:00 2001
From: Minwoo Jung <jmwsoft@gmail.com>
Date: Fri, 21 Aug 2015 14:30:08 -0700
Subject: [PATCH 01/23] lib: use arrow functions instead of bind

use `arrow functions` instead of `bind(this)` in order to improve
performance through optimizations.

PR-URL: https://github.com/nodejs/node/pull/3622
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
---
 lib/_debugger.js   | 16 +++++++++-------
 lib/_tls_legacy.js | 11 ++++++-----
 lib/_tls_wrap.js   | 14 +++++++-------
 lib/cluster.js     | 12 +++++++++---
 lib/fs.js          |  2 +-
 lib/net.js         |  6 +++---
 6 files changed, 35 insertions(+), 26 deletions(-)

diff --git a/lib/_debugger.js b/lib/_debugger.js
index 90a001f0185a0d..258e45cd461085 100644
--- a/lib/_debugger.js
+++ b/lib/_debugger.js
@@ -159,7 +159,7 @@ function Client() {
     protocol.execute(d);
   });
 
-  protocol.onResponse = this._onResponse.bind(this);
+  protocol.onResponse = (res) => this._onResponse(res);
 }
 inherits(Client, net.Socket);
 exports.Client = Client;
@@ -734,7 +734,7 @@ function Interface(stdin, stdout, args) {
     prompt: 'debug> ',
     input: this.stdin,
     output: this.stdout,
-    eval: this.controlEval.bind(this),
+    eval: (code, ctx, file, cb) => this.controlEval(code, ctx, file, cb),
     useGlobal: false,
     ignoreUndefined: true
   };
@@ -765,7 +765,7 @@ function Interface(stdin, stdout, args) {
   });
 
   // Handle all possible exits
-  process.on('exit', this.killChild.bind(this));
+  process.on('exit', () => this.killChild());
   process.once('SIGTERM', process.exit.bind(process, 0));
   process.once('SIGHUP', process.exit.bind(process, 0));
 
@@ -1587,7 +1587,8 @@ Interface.prototype.repl = function() {
   this.repl.on('exit', exitDebugRepl);
 
   // Set new
-  this.repl.eval = this.debugEval.bind(this);
+  this.repl.eval = (code, ctx, file, cb) =>
+    this.debugEval(code, ctx, file, cb);
   this.repl.context = {};
 
   // Swap history
@@ -1602,7 +1603,8 @@ Interface.prototype.repl = function() {
 // Exit debug repl
 Interface.prototype.exitRepl = function() {
   // Restore eval
-  this.repl.eval = this.controlEval.bind(this);
+  this.repl.eval = (code, ctx, file, cb) =>
+    this.controlEval(code, ctx, file, cb);
 
   // Swap history
   this.history.debug = this.repl.rli.history;
@@ -1689,8 +1691,8 @@ Interface.prototype.trySpawn = function(cb) {
     // pipe stream into debugger
     this.child = spawn(process.execPath, childArgs);
 
-    this.child.stdout.on('data', this.childPrint.bind(this));
-    this.child.stderr.on('data', this.childPrint.bind(this));
+    this.child.stdout.on('data', (text) => this.childPrint(text));
+    this.child.stderr.on('data', (text) => this.childPrint(text));
   }
 
   this.pause();
diff --git a/lib/_tls_legacy.js b/lib/_tls_legacy.js
index 8c079e341b5b05..35a1a15cce9fd9 100644
--- a/lib/_tls_legacy.js
+++ b/lib/_tls_legacy.js
@@ -704,14 +704,15 @@ function SecurePair(context, isServer, requestCert, rejectUnauthorized,
                             this._rejectUnauthorized);
 
   if (this._isServer) {
-    this.ssl.onhandshakestart = onhandshakestart.bind(this);
-    this.ssl.onhandshakedone = onhandshakedone.bind(this);
-    this.ssl.onclienthello = onclienthello.bind(this);
-    this.ssl.onnewsession = onnewsession.bind(this);
+    this.ssl.onhandshakestart = () => onhandshakestart.call(this);
+    this.ssl.onhandshakedone = () => onhandshakedone.call(this);
+    this.ssl.onclienthello = (hello) => onclienthello.call(this, hello);
+    this.ssl.onnewsession =
+        (key, session) => onnewsession.call(this, key, session);
     this.ssl.lastHandshakeTime = 0;
     this.ssl.handshakes = 0;
   } else {
-    this.ssl.onocspresponse = onocspresponse.bind(this);
+    this.ssl.onocspresponse = (resp) => onocspresponse.call(this, resp);
   }
 
   if (process.features.tls_sni) {
diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js
index 999b4767576711..8f98d399e15602 100644
--- a/lib/_tls_wrap.js
+++ b/lib/_tls_wrap.js
@@ -407,11 +407,11 @@ TLSSocket.prototype._init = function(socket, wrap) {
     ssl.setVerifyMode(requestCert, rejectUnauthorized);
 
   if (options.isServer) {
-    ssl.onhandshakestart = onhandshakestart.bind(this);
-    ssl.onhandshakedone = onhandshakedone.bind(this);
-    ssl.onclienthello = onclienthello.bind(this);
-    ssl.oncertcb = oncertcb.bind(this);
-    ssl.onnewsession = onnewsession.bind(this);
+    ssl.onhandshakestart = () => onhandshakestart.call(this);
+    ssl.onhandshakedone = () => onhandshakedone.call(this);
+    ssl.onclienthello = (hello) => onclienthello.call(this, hello);
+    ssl.oncertcb = (info) => oncertcb.call(this, info);
+    ssl.onnewsession = (key, session) => onnewsession.call(this, key, session);
     ssl.lastHandshakeTime = 0;
     ssl.handshakes = 0;
 
@@ -425,8 +425,8 @@ TLSSocket.prototype._init = function(socket, wrap) {
     }
   } else {
     ssl.onhandshakestart = function() {};
-    ssl.onhandshakedone = this._finishInit.bind(this);
-    ssl.onocspresponse = onocspresponse.bind(this);
+    ssl.onhandshakedone = () => this._finishInit();
+    ssl.onocspresponse = (resp) => onocspresponse.call(this, resp);
 
     if (options.session)
       ssl.setSession(options.session);
diff --git a/lib/cluster.js b/lib/cluster.js
index f202f25cdd522a..6ab829de450f5d 100644
--- a/lib/cluster.js
+++ b/lib/cluster.js
@@ -33,8 +33,12 @@ function Worker(options) {
 
   if (options.process) {
     this.process = options.process;
-    this.process.on('error', this.emit.bind(this, 'error'));
-    this.process.on('message', this.emit.bind(this, 'message'));
+    this.process.on('error', (code, signal) =>
+      this.emit('error', code, signal)
+    );
+    this.process.on('message', (message, handle) =>
+      this.emit('message', message, handle)
+    );
   }
 }
 util.inherits(Worker, EventEmitter);
@@ -337,7 +341,9 @@ function masterInit() {
       process: workerProcess
     });
 
-    worker.on('message', this.emit.bind(this, 'message'));
+    worker.on('message', (message, handle) =>
+      this.emit('message', message, handle)
+    );
 
     worker.process.once('exit', function(exitCode, signalCode) {
       /*
diff --git a/lib/fs.js b/lib/fs.js
index fe9ae991b8be64..76c83f455bcbee 100644
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -1842,7 +1842,7 @@ ReadStream.prototype.close = function(cb) {
       this.once('open', close);
       return;
     }
-    return process.nextTick(this.emit.bind(this, 'close'));
+    return process.nextTick(() => this.emit('close'));
   }
   this.closed = true;
   close();
diff --git a/lib/net.js b/lib/net.js
index f778043572362e..f8f989ed662ac2 100644
--- a/lib/net.js
+++ b/lib/net.js
@@ -322,7 +322,7 @@ Socket.prototype._onTimeout = function() {
 Socket.prototype.setNoDelay = function(enable) {
   if (!this._handle) {
     this.once('connect',
-              enable ? this.setNoDelay : this.setNoDelay.bind(this, enable));
+              enable ? this.setNoDelay : () => this.setNoDelay(enable));
     return this;
   }
 
@@ -336,7 +336,7 @@ Socket.prototype.setNoDelay = function(enable) {
 
 Socket.prototype.setKeepAlive = function(setting, msecs) {
   if (!this._handle) {
-    this.once('connect', this.setKeepAlive.bind(this, setting, msecs));
+    this.once('connect', () => this.setKeepAlive(setting, msecs));
     return this;
   }
 
@@ -384,7 +384,7 @@ Socket.prototype._read = function(n) {
 
   if (this._connecting || !this._handle) {
     debug('_read wait for connection');
-    this.once('connect', this._read.bind(this, n));
+    this.once('connect', () => this._read(n));
   } else if (!this._handle.reading) {
     // not already reading, start the flow
     debug('Socket._read readStart');

From 8c718543ad55b4ef4b6ab56774899229de6eb604 Mon Sep 17 00:00:00 2001
From: Nicholas Young <nicholas@nicholaswyoung.com>
Date: Thu, 17 Dec 2015 09:38:44 -0600
Subject: [PATCH 02/23] doc: fix link in addons.markdown

Update link from github.com/rvagg to github.com/nodejs

PR-URL: https://github.com/nodejs/node/pull/4331
Reviewed-By: James M Snell <jasnell@gmail.com>
---
 doc/api/addons.markdown | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown
index 9a66c317bf337f..d9501eeb862363 100644
--- a/doc/api/addons.markdown
+++ b/doc/api/addons.markdown
@@ -870,7 +870,7 @@ Test in JavaScript by running:
 
 [online]: https://v8docs.nodesource.com/
 [libuv]: https://github.com/libuv/libuv
-[download]: https://github.com/rvagg/node-addon-examples
+[download]: https://github.com/nodejs/node-addon-examples
 [node-gyp]: https://github.com/nodejs/node-gyp
 [v8 reference]: http://izs.me/v8-docs/main.html
 [Embedder's Guide]: https://code.google.com/apis/v8/embed.html

From 1dd09a8fbab94db1c12fad8056d759a5ac64cf35 Mon Sep 17 00:00:00 2001
From: chrisjohn404 <chris.s.johnson4@gmail.com>
Date: Thu, 17 Dec 2015 01:11:48 -0700
Subject: [PATCH 03/23] doc: Typo in buffer.markdown referencing buf.write()

The buffer's write function is documented below the
buf.toString function and all of the docs reference
"buf" instead of "buffer".

PR-URL: https://github.com/nodejs/node/pull/4324
Reviewed-By: James M Snell <jasnell@gmail.com>
---
 doc/api/buffer.markdown | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/api/buffer.markdown b/doc/api/buffer.markdown
index 9fd57040816447..cd28ce20239206 100644
--- a/doc/api/buffer.markdown
+++ b/doc/api/buffer.markdown
@@ -611,7 +611,7 @@ defaults to `'utf8'`. The `start` and `end` parameters default to `0` and
     buf.toString('utf8',0,5); // outputs: abcde
     buf.toString(undefined,0,5); // encoding defaults to 'utf8', outputs abcde
 
-See `buffer.write()` example, above.
+See `buf.write()` example, below.
 
 
 ### buf.toJSON()

From 46c44c830f7b44fcefb10dc9dd50606666aa00a2 Mon Sep 17 00:00:00 2001
From: James M Snell <jasnell@gmail.com>
Date: Mon, 14 Dec 2015 15:20:25 -0800
Subject: [PATCH 04/23] doc: fix, modernize examples in docs

* Use single quotes consistently
* Modernize examples to use template strings and arrow funcs
* Fix a few typos
* Example edits for consistency

PR-URL: https://github.com/nodejs/node/pull/4282
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
---
 doc/api/addons.markdown         |  18 ++---
 doc/api/assert.markdown         |  14 ++--
 doc/api/buffer.markdown         |  12 +--
 doc/api/child_process.markdown  | 132 ++++++++++++++++----------------
 doc/api/cluster.markdown        |  95 +++++++++++------------
 doc/api/console.markdown        |  10 +--
 doc/api/crypto.markdown         |  44 +++++------
 doc/api/debugger.markdown       |  14 ++--
 doc/api/dgram.markdown          |  34 ++++----
 doc/api/dns.markdown            |  70 ++++++++---------
 doc/api/domain.markdown         |  56 +++++++-------
 doc/api/errors.markdown         |  24 +++---
 doc/api/events.markdown         |  10 +--
 doc/api/fs.markdown             |  42 +++++-----
 doc/api/http.markdown           |  74 +++++++++---------
 doc/api/https.markdown          |  48 ++++++------
 doc/api/modules.markdown        |  33 ++++----
 doc/api/net.markdown            |  45 ++++++-----
 doc/api/process.markdown        | 104 ++++++++++++-------------
 doc/api/readline.markdown       |  42 +++++-----
 doc/api/repl.markdown           |  26 +++----
 doc/api/stream.markdown         |  88 ++++++++++-----------
 doc/api/string_decoder.markdown |   8 +-
 doc/api/synopsis.markdown       |   4 +-
 doc/api/tls.markdown            |  52 ++++++-------
 doc/api/tty.markdown            |   4 +-
 doc/api/util.markdown           |  50 ++++++------
 doc/api/v8.markdown             |   2 +-
 doc/api/vm.markdown             |  40 +++++-----
 doc/api/zlib.markdown           |  32 ++++----
 30 files changed, 613 insertions(+), 614 deletions(-)

diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown
index d9501eeb862363..aa343d73192ce8 100644
--- a/doc/api/addons.markdown
+++ b/doc/api/addons.markdown
@@ -99,7 +99,7 @@ You can now use the binary addon in a Node.js project `hello.js` by pointing
 `require` to the recently built `hello.node` module:
 
     // hello.js
-    var addon = require('./build/Release/addon');
+    const addon = require('./build/Release/addon');
 
     console.log(addon.hello()); // 'world'
 
@@ -189,7 +189,7 @@ function calls and return a result. This is the main and only needed source
 You can test it with the following JavaScript snippet:
 
     // test.js
-    var addon = require('./build/Release/addon');
+    const addon = require('./build/Release/addon');
 
     console.log( 'This should be eight:', addon.add(3,5) );
 
@@ -237,7 +237,7 @@ adding the function as a property of `exports`.
 To test it, run the following JavaScript snippet:
 
     // test.js
-    var addon = require('./build/Release/addon');
+    const addon = require('./build/Release/addon');
 
     addon(function(msg){
       console.log(msg); // 'hello world'
@@ -282,7 +282,7 @@ the string passed to `createObject()`:
 To test it in JavaScript:
 
     // test.js
-    var addon = require('./build/Release/addon');
+    const addon = require('./build/Release/addon');
 
     var obj1 = addon('hello');
     var obj2 = addon('world');
@@ -336,7 +336,7 @@ wraps a C++ function:
 To test:
 
     // test.js
-    var addon = require('./build/Release/addon');
+    const addon = require('./build/Release/addon');
 
     var fn = addon();
     console.log(fn()); // 'hello world'
@@ -470,7 +470,7 @@ prototype:
 Test it with:
 
     // test.js
-    var addon = require('./build/Release/addon');
+    const addon = require('./build/Release/addon');
 
     var obj = new addon.MyObject(10);
     console.log( obj.plusOne() ); // 11
@@ -630,7 +630,7 @@ The implementation is similar to the above in `myobject.cc`:
 Test it with:
 
     // test.js
-    var createObject = require('./build/Release/addon');
+    const createObject = require('./build/Release/addon');
 
     var obj = createObject(10);
     console.log( obj.plusOne() ); // 11
@@ -792,7 +792,7 @@ The implementation of `myobject.cc` is similar to before:
 Test it with:
 
     // test.js
-    var addon = require('./build/Release/addon');
+    const addon = require('./build/Release/addon');
 
     var obj1 = addon.createObject(10);
     var obj2 = addon.createObject(20);
@@ -866,7 +866,7 @@ The file `addon.cc` implements AtExit below:
 Test in JavaScript by running:
 
     // test.js
-    var addon = require('./build/Release/addon');
+    const addon = require('./build/Release/addon');
 
 [online]: https://v8docs.nodesource.com/
 [libuv]: https://github.com/libuv/libuv
diff --git a/doc/api/assert.markdown b/doc/api/assert.markdown
index a3fb229161b31e..eb334696805298 100644
--- a/doc/api/assert.markdown
+++ b/doc/api/assert.markdown
@@ -41,7 +41,7 @@ assertion.
 
     assert.doesNotThrow(
       function() {
-        throw new TypeError("Wrong value");
+        throw new TypeError('Wrong value');
       },
       SyntaxError
     );
@@ -51,7 +51,7 @@ is thrown instead.
 
     assert.doesNotThrow(
       function() {
-        throw new TypeError("Wrong value");
+        throw new TypeError('Wrong value');
       },
       TypeError
     );
@@ -102,7 +102,7 @@ Validate instanceof using constructor:
 
     assert.throws(
       function() {
-        throw new Error("Wrong value");
+        throw new Error('Wrong value');
       },
       Error
     );
@@ -111,7 +111,7 @@ Validate error message using [`RegExp`][]:
 
     assert.throws(
       function() {
-        throw new Error("Wrong value");
+        throw new Error('Wrong value');
       },
       /value/
     );
@@ -120,14 +120,14 @@ Custom error validation:
 
     assert.throws(
       function() {
-        throw new Error("Wrong value");
+        throw new Error('Wrong value');
       },
       function(err) {
         if ( (err instanceof Error) && /value/.test(err) ) {
           return true;
         }
       },
-      "unexpected error"
+      'unexpected error'
     );
 
 [`assert.deepEqual`]: #assert_assert_deepequal_actual_expected_message
@@ -135,4 +135,4 @@ Custom error validation:
 [`assert.throws()`]: #assert_assert_throws_block_error_message
 [`Error`]: errors.html#errors_class_error
 [`RegExp`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
-[`TypeError`]: errors.html#errors_class_typeerror
\ No newline at end of file
+[`TypeError`]: errors.html#errors_class_typeerror
diff --git a/doc/api/buffer.markdown b/doc/api/buffer.markdown
index cd28ce20239206..c5c972006ad3d4 100644
--- a/doc/api/buffer.markdown
+++ b/doc/api/buffer.markdown
@@ -104,8 +104,8 @@ Example:
 
     str = '\u00bd + \u00bc = \u00be';
 
-    console.log(str + ": " + str.length + " characters, " +
-      Buffer.byteLength(str, 'utf8') + " bytes");
+    console.log(`${str}: ${str.length} characters, ` +
+                `${Buffer.byteLength(str, 'utf8')} bytes`);
 
     // ½ + ¼ = ¾: 9 characters, 12 bytes
 
@@ -277,7 +277,7 @@ and `end` (defaults to `buffer.length`) are not given it will fill the entire
 buffer.
 
     var b = new Buffer(50);
-    b.fill("h");
+    b.fill('h');
 
 ### buf.indexOf(value[, byteOffset])
 
@@ -314,7 +314,7 @@ buffer object.  It does not change when the contents of the buffer are changed.
     buf = new Buffer(1234);
 
     console.log(buf.length);
-    buf.write("some string", 0, "ascii");
+    buf.write('some string', 0, 'ascii');
     console.log(buf.length);
 
     // 1234
@@ -326,7 +326,7 @@ modify the length of a buffer should therefore treat `length` as read-only and
 use [`buf.slice`][] to create a new buffer.
 
     buf = new Buffer(10);
-    buf.write("abcdefghj", 0, "ascii");
+    buf.write('abcdefghj', 0, 'ascii');
     console.log(buf.length); // 10
     buf = buf.slice(0,5);
     console.log(buf.length); // 5
@@ -652,7 +652,7 @@ The method will not write partial characters.
 
     buf = new Buffer(256);
     len = buf.write('\u00bd + \u00bc = \u00be', 0);
-    console.log(len + " bytes: " + buf.toString('utf8', 0, len));
+    console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`);
 
 ### buf.writeDoubleBE(value, offset[, noAssert])
 ### buf.writeDoubleLE(value, offset[, noAssert])
diff --git a/doc/api/child_process.markdown b/doc/api/child_process.markdown
index e9e4b3711cbf72..4491979c3a4a7d 100644
--- a/doc/api/child_process.markdown
+++ b/doc/api/child_process.markdown
@@ -115,11 +115,12 @@ child process has any open IPC channels with the parent (i.e [`fork()`][]).
 Send a signal to the child process. If no argument is given, the process will
 be sent `'SIGTERM'`. See `signal(7)` for a list of available signals.
 
-    var spawn = require('child_process').spawn,
-        grep  = spawn('grep', ['ssh']);
+    const spawn = require('child_process').spawn;
+    const grep = spawn('grep', ['ssh']);
 
-    grep.on('close', function (code, signal) {
-      console.log('child process terminated due to receipt of signal ' + signal);
+    grep.on('close', (code, signal) => {
+      console.log(
+        `child process terminated due to receipt of signal ${signal}`);
     });
 
     // send SIGHUP to process
@@ -145,10 +146,10 @@ The process identifier (PID) of the child process.
 
 Example:
 
-    var spawn = require('child_process').spawn,
-        grep  = spawn('grep', ['ssh']);
+    const spawn = require('child_process').spawn;
+    const grep = spawn('grep', ['ssh']);
 
-    console.log('Spawned child pid: ' + grep.pid);
+    console.log(`Spawned child pid: ${grep.pid}`);
     grep.stdin.end();
 
 ### child.send(message[, sendHandle][, callback])
@@ -164,11 +165,10 @@ a `'message'` event on the child.
 
 For example:
 
-    var cp = require('child_process');
+    const cp = require('child_process');
+    const n = cp.fork(`${__dirname}/sub.js`);
 
-    var n = cp.fork(__dirname + '/sub.js');
-
-    n.on('message', function(m) {
+    n.on('message', (m) => {
       console.log('PARENT got message:', m);
     });
 
@@ -176,7 +176,7 @@ For example:
 
 And then the child script, `'sub.js'` might look like this:
 
-    process.on('message', function(m) {
+    process.on('message', (m) => {
       console.log('CHILD got message:', m);
     });
 
@@ -211,22 +211,22 @@ control.
 
 Here is an example of sending a server:
 
-    var child = require('child_process').fork('child.js');
+    const child = require('child_process').fork('child.js');
 
     // Open up the server object and send the handle.
-    var server = require('net').createServer();
-    server.on('connection', function (socket) {
+    const server = require('net').createServer();
+    server.on('connection', (socket) => {
       socket.end('handled by parent');
     });
-    server.listen(1337, function() {
+    server.listen(1337, () => {
       child.send('server', server);
     });
 
 And the child would then receive the server object as:
 
-    process.on('message', function(m, server) {
+    process.on('message', (m, server) => {
       if (m === 'server') {
-        server.on('connection', function (socket) {
+        server.on('connection', (socket) => {
           socket.end('handled by child');
         });
       }
@@ -246,12 +246,12 @@ connections with the remote address `74.125.127.100` as VIP by sending the
 socket to a "special" child process. Other sockets will go to a "normal"
 process.
 
-    var normal = require('child_process').fork('child.js', ['normal']);
-    var special = require('child_process').fork('child.js', ['special']);
+    const normal = require('child_process').fork('child.js', ['normal']);
+    const special = require('child_process').fork('child.js', ['special']);
 
     // Open up the server and send sockets to child
-    var server = require('net').createServer();
-    server.on('connection', function (socket) {
+    const server = require('net').createServer();
+    server.on('connection', (socket) => {
 
       // if this is a VIP
       if (socket.remoteAddress === '74.125.127.100') {
@@ -265,9 +265,9 @@ process.
 
 The `child.js` could look like this:
 
-    process.on('message', function(m, socket) {
+    process.on('message', (m, socket) => {
       if (m === 'socket') {
-        socket.end('You were handled as a ' + process.argv[2] + ' person');
+        socket.end(`You were handled as a ${process.argv[2]} person`);
       }
     });
 
@@ -315,11 +315,11 @@ In the following example, only the child's fd `1` is setup as a pipe, so only
 the parent's `child.stdio[1]` is a stream, all other values in the array are
 `null`.
 
-    var assert = require('assert');
-    var fs = require('fs');
-    var child_process = require('child_process');
+    const assert = require('assert');
+    const fs = require('fs');
+    const child_process = require('child_process');
 
-    child = child_process.spawn('ls', {
+    const child = child_process.spawn('ls', {
         stdio: [
           0, // use parents stdin for child
           'pipe', // pipe child's stdout to parent
@@ -378,15 +378,13 @@ callback or returning an EventEmitter).
 
 Runs a command in a shell and buffers the output.
 
-    var exec = require('child_process').exec,
-        child;
-
-    child = exec('cat *.js bad_file | wc -l',
-      function (error, stdout, stderr) {
-        console.log('stdout: ' + stdout);
-        console.log('stderr: ' + stderr);
+    const exec = require('child_process').exec;
+    const child = exec('cat *.js bad_file | wc -l',
+      (error, stdout, stderr) => {
+        console.log(`stdout: ${stdout}`);
+        console.log(`stderr: ${stderr}`);
         if (error !== null) {
-          console.log('exec error: ' + error);
+          console.log(`exec error: ${error}`);
         }
     });
 
@@ -508,64 +506,64 @@ process, the default is `process.env`.
 
 Example of running `ls -lh /usr`, capturing `stdout`, `stderr`, and the exit code:
 
-    var spawn = require('child_process').spawn,
-        ls    = spawn('ls', ['-lh', '/usr']);
+    const spawn = require('child_process').spawn;
+    const ls = spawn('ls', ['-lh', '/usr']);
 
-    ls.stdout.on('data', function (data) {
-      console.log('stdout: ' + data);
+    ls.stdout.on('data', (data) => {
+      console.log(`stdout: ${data}`);
     });
 
-    ls.stderr.on('data', function (data) {
-      console.log('stderr: ' + data);
+    ls.stderr.on('data', (data) => {
+      console.log(`stderr: ${data}`);
     });
 
-    ls.on('close', function (code) {
-      console.log('child process exited with code ' + code);
+    ls.on('close', (code) => {
+      console.log(`child process exited with code ${code}`);
     });
 
 
 Example: A very elaborate way to run 'ps ax | grep ssh'
 
-    var spawn = require('child_process').spawn,
-        ps    = spawn('ps', ['ax']),
-        grep  = spawn('grep', ['ssh']);
+    const spawn = require('child_process').spawn;
+    const ps = spawn('ps', ['ax']);
+    const grep = spawn('grep', ['ssh']);
 
-    ps.stdout.on('data', function (data) {
+    ps.stdout.on('data', (data) => {
       grep.stdin.write(data);
     });
 
-    ps.stderr.on('data', function (data) {
-      console.log('ps stderr: ' + data);
+    ps.stderr.on('data', (data) => {
+      console.log(`ps stderr: ${data}`);
     });
 
-    ps.on('close', function (code) {
+    ps.on('close', (code) => {
       if (code !== 0) {
-        console.log('ps process exited with code ' + code);
+        console.log(`ps process exited with code ${code}`);
       }
       grep.stdin.end();
     });
 
-    grep.stdout.on('data', function (data) {
-      console.log('' + data);
+    grep.stdout.on('data', (data) => {
+      console.log(`${data}`);
     });
 
-    grep.stderr.on('data', function (data) {
-      console.log('grep stderr: ' + data);
+    grep.stderr.on('data', (data) => {
+      console.log(`grep stderr: ${data}`);
     });
 
-    grep.on('close', function (code) {
+    grep.on('close', (code) => {
       if (code !== 0) {
-        console.log('grep process exited with code ' + code);
+        console.log(`grep process exited with code ${code}`);
       }
     });
 
 
 Example of checking for failed exec:
 
-    var spawn = require('child_process').spawn,
-        child = spawn('bad_command');
+    const spawn = require('child_process').spawn;
+    const child = spawn('bad_command');
 
-    child.on('error', function (err) {
+    child.on('error', (err) => {
       console.log('Failed to start child process.');
     });
 
@@ -587,12 +585,12 @@ and the parent's event loop will not include the child in its reference count.
 Example of detaching a long-running process and redirecting its output to a
 file:
 
-     var fs = require('fs'),
-         spawn = require('child_process').spawn,
-         out = fs.openSync('./out.log', 'a'),
-         err = fs.openSync('./out.log', 'a');
+     const fs = require('fs');
+     const spawn = require('child_process').spawn;
+     const out = fs.openSync('./out.log', 'a');
+     const err = fs.openSync('./out.log', 'a');
 
-     var child = spawn('prg', [], {
+     const child = spawn('prg', [], {
        detached: true,
        stdio: [ 'ignore', out, err ]
      });
@@ -646,7 +644,7 @@ index corresponds to a fd in the child.  The value is one of the following:
 
 Example:
 
-    var spawn = require('child_process').spawn;
+    const spawn = require('child_process').spawn;
 
     // Child will use parent's stdios
     spawn('prg', [], { stdio: 'inherit' });
diff --git a/doc/api/cluster.markdown b/doc/api/cluster.markdown
index d300b274a1627e..b29c13694b00fd 100644
--- a/doc/api/cluster.markdown
+++ b/doc/api/cluster.markdown
@@ -9,9 +9,9 @@ processes to handle the load.
 The cluster module allows you to easily create child processes that
 all share server ports.
 
-    var cluster = require('cluster');
-    var http = require('http');
-    var numCPUs = require('os').cpus().length;
+    const cluster = require('cluster');
+    const http = require('http');
+    const numCPUs = require('os').cpus().length;
 
     if (cluster.isMaster) {
       // Fork workers.
@@ -19,15 +19,15 @@ all share server ports.
         cluster.fork();
       }
 
-      cluster.on('exit', function(worker, code, signal) {
-        console.log('worker ' + worker.process.pid + ' died');
+      cluster.on('exit', (worker, code, signal) => {
+        console.log(`worker ${worker.process.pid} died`);
       });
     } else {
       // Workers can share any TCP connection
       // In this case it is an HTTP server
-      http.createServer(function(req, res) {
+      http.createServer((req, res) => {
         res.writeHead(200);
-        res.end("hello world\n");
+        res.end('hello world\n');
       }).listen(8000);
     }
 
@@ -113,7 +113,7 @@ it can be obtained using `cluster.worker`.
 
 Similar to the `cluster.on('disconnect')` event, but specific to this worker.
 
-    cluster.fork().on('disconnect', function() {
+    cluster.fork().on('disconnect', () => {
       // Worker has disconnected
     });
 
@@ -131,14 +131,14 @@ In a worker you can also use `process.on('error')`.
 
 Similar to the `cluster.on('exit')` event, but specific to this worker.
 
-    var worker = cluster.fork();
-    worker.on('exit', function(code, signal) {
+    const worker = cluster.fork();
+    worker.on('exit', (code, signal) => {
       if( signal ) {
-        console.log("worker was killed by signal: "+signal);
+        console.log(`worker was killed by signal: ${signal}`);
       } else if( code !== 0 ) {
-        console.log("worker exited with error code: "+code);
+        console.log(`worker exited with error code: ${code}`);
       } else {
-        console.log("worker success!");
+        console.log('worker success!');
       }
     });
 
@@ -148,7 +148,7 @@ Similar to the `cluster.on('exit')` event, but specific to this worker.
 
 Similar to the `cluster.on('listening')` event, but specific to this worker.
 
-    cluster.fork().on('listening', function(address) {
+    cluster.fork().on('listening', (address) => {
       // Worker is listening
     });
 
@@ -167,15 +167,15 @@ In a worker you can also use `process.on('message')`.
 As an example, here is a cluster that keeps count of the number of requests
 in the master process using the message system:
 
-    var cluster = require('cluster');
-    var http = require('http');
+    const cluster = require('cluster');
+    const http = require('http');
 
     if (cluster.isMaster) {
 
       // Keep track of http requests
       var numReqs = 0;
-      setInterval(function() {
-        console.log("numReqs =", numReqs);
+      setInterval(() => {
+        console.log('numReqs =', numReqs);
       }, 1000);
 
       // Count requests
@@ -186,21 +186,21 @@ in the master process using the message system:
       }
 
       // Start workers and listen for messages containing notifyRequest
-      var numCPUs = require('os').cpus().length;
+      const numCPUs = require('os').cpus().length;
       for (var i = 0; i < numCPUs; i++) {
         cluster.fork();
       }
 
-      Object.keys(cluster.workers).forEach(function(id) {
+      Object.keys(cluster.workers).forEach((id) => {
         cluster.workers[id].on('message', messageHandler);
       });
 
     } else {
 
       // Worker processes have a http server.
-      http.Server(function(req, res) {
+      http.Server((req, res) => {
         res.writeHead(200);
-        res.end("hello world\n");
+        res.end('hello world\n');
 
         // notify master about the request
         process.send({ cmd: 'notifyRequest' });
@@ -211,7 +211,7 @@ in the master process using the message system:
 
 Similar to the `cluster.on('online')` event, but specific to this worker.
 
-    cluster.fork().on('online', function() {
+    cluster.fork().on('online', () => {
       // Worker is online
     });
 
@@ -249,27 +249,27 @@ the `'disconnect'` event has not been emitted after some time.
       var worker = cluster.fork();
       var timeout;
 
-      worker.on('listening', function(address) {
+      worker.on('listening', (address) => {
         worker.send('shutdown');
         worker.disconnect();
-        timeout = setTimeout(function() {
+        timeout = setTimeout(() => {
           worker.kill();
         }, 2000);
       });
 
-      worker.on('disconnect', function() {
+      worker.on('disconnect', () => {
         clearTimeout(timeout);
       });
 
     } else if (cluster.isWorker) {
-      var net = require('net');
-      var server = net.createServer(function(socket) {
+      const net = require('net');
+      var server = net.createServer((socket) => {
         // connections never end
       });
 
       server.listen(8000);
 
-      process.on('message', function(msg) {
+      process.on('message', (msg) => {
         if(msg === 'shutdown') {
           // initiate graceful close of any connections to server
         }
@@ -349,7 +349,7 @@ This example will echo back all messages from the master:
       worker.send('hi there');
 
     } else if (cluster.isWorker) {
-      process.on('message', function(msg) {
+      process.on('message', (msg) => {
         process.send(msg);
       });
     }
@@ -363,7 +363,7 @@ Set by calling `.kill()` or `.disconnect()`, until then it is `undefined`.
 The boolean `worker.suicide` lets you distinguish between voluntary and accidental
 exit, the master may choose not to respawn a worker based on this value.
 
-    cluster.on('exit', function(worker, code, signal) {
+    cluster.on('exit', (worker, code, signal) => {
       if (worker.suicide === true) {
         console.log('Oh, it was just suicide\' – no need to worry').
       }
@@ -384,8 +384,8 @@ There may be a delay between the `'disconnect'` and `'exit'` events.  These even
 can be used to detect if the process is stuck in a cleanup or if there are
 long-living connections.
 
-    cluster.on('disconnect', function(worker) {
-      console.log('The worker #' + worker.id + ' has disconnected');
+    cluster.on('disconnect', (worker) => {
+      console.log(`The worker #${worker.id} has disconnected`);
     });
 
 ## Event: 'exit'
@@ -399,7 +399,7 @@ When any of the workers die the cluster module will emit the `'exit'` event.
 
 This can be used to restart the worker by calling `.fork()` again.
 
-    cluster.on('exit', function(worker, code, signal) {
+    cluster.on('exit', (worker, code, signal) => {
       console.log('worker %d died (%s). restarting...',
         worker.process.pid, signal || code);
       cluster.fork();
@@ -416,16 +416,16 @@ This can be used to log worker activity, and create your own timeout.
 
     var timeouts = [];
     function errorMsg() {
-      console.error("Something must be wrong with the connection ...");
+      console.error('Something must be wrong with the connection ...');
     }
 
-    cluster.on('fork', function(worker) {
+    cluster.on('fork', (worker) => {
       timeouts[worker.id] = setTimeout(errorMsg, 2000);
     });
-    cluster.on('listening', function(worker, address) {
+    cluster.on('listening', (worker, address) => {
       clearTimeout(timeouts[worker.id]);
     });
-    cluster.on('exit', function(worker, code, signal) {
+    cluster.on('exit', (worker, code, signal) => {
       clearTimeout(timeouts[worker.id]);
       errorMsg();
     });
@@ -443,8 +443,9 @@ object and the `address` object contains the following connection properties:
 `address`, `port` and `addressType`. This is very useful if the worker is listening
 on more than one address.
 
-    cluster.on('listening', function(worker, address) {
-      console.log("A worker is now connected to " + address.address + ":" + address.port);
+    cluster.on('listening', (worker, address) => {
+      console.log(
+        `A worker is now connected to ${address.address}:${address.port}`);
     });
 
 The `addressType` is one of:
@@ -472,8 +473,8 @@ When the master receives an online message it will emit this event.
 The difference between `'fork'` and `'online'` is that fork is emitted when the
 master forks a worker, and 'online' is emitted when the worker is running.
 
-    cluster.on('online', function(worker) {
-      console.log("Yay, the worker responded after it was forked");
+    cluster.on('online', (worker) => {
+      console.log('Yay, the worker responded after it was forked');
     });
 
 ## Event: 'setup'
@@ -584,7 +585,7 @@ Note that:
 
 Example:
 
-    var cluster = require('cluster');
+    const cluster = require('cluster');
     cluster.setupMaster({
       exec: 'worker.js',
       args: ['--use', 'https'],
@@ -604,14 +605,14 @@ This can only be called from the master process.
 
 A reference to the current worker object. Not available in the master process.
 
-    var cluster = require('cluster');
+    const cluster = require('cluster');
 
     if (cluster.isMaster) {
       console.log('I am master');
       cluster.fork();
       cluster.fork();
     } else if (cluster.isWorker) {
-      console.log('I am worker #' + cluster.worker.id);
+      console.log(`I am worker #${cluster.worker.id}`);
     }
 
 ## cluster.workers
@@ -633,14 +634,14 @@ before last `'disconnect'` or `'exit'` event is emitted.
         callback(cluster.workers[id]);
       }
     }
-    eachWorker(function(worker) {
+    eachWorker((worker) => {
       worker.send('big announcement to all workers');
     });
 
 Should you wish to reference a worker over a communication channel, using
 the worker's unique id is the easiest way to find the worker.
 
-    socket.on('data', function(id) {
+    socket.on('data', (id) => {
       var worker = cluster.workers[id];
     });
 
diff --git a/doc/api/console.markdown b/doc/api/console.markdown
index 6343ca781c3dd1..b3659a1187315a 100644
--- a/doc/api/console.markdown
+++ b/doc/api/console.markdown
@@ -16,8 +16,8 @@ directly without `require`.
 
 Use `require('console').Console` or `console.Console` to access this class.
 
-    var Console = require('console').Console;
-    var Console = console.Console;
+    const Console = require('console').Console;
+    const Console = console.Console;
 
 You can use the `Console` class to create a simple logger like `console` but
 with different output streams.
@@ -29,10 +29,10 @@ Create a new `Console` by passing one or two writable stream instances.
 is used for warning or error output. If `stderr` isn't passed, the warning
 and error output will be sent to the `stdout`.
 
-    var output = fs.createWriteStream('./stdout.log');
-    var errorOutput = fs.createWriteStream('./stderr.log');
+    const output = fs.createWriteStream('./stdout.log');
+    const errorOutput = fs.createWriteStream('./stderr.log');
     // custom simple logger
-    var logger = new Console(output, errorOutput);
+    const logger = new Console(output, errorOutput);
     // use it like console
     var count = 5;
     logger.log('count: %d', count);
diff --git a/doc/api/crypto.markdown b/doc/api/crypto.markdown
index f90ec1c429a826..a731d979ac88da 100644
--- a/doc/api/crypto.markdown
+++ b/doc/api/crypto.markdown
@@ -280,9 +280,9 @@ associated with the private key being set.
 
 Example (obtaining a shared secret):
 
-    var crypto = require('crypto');
-    var alice = crypto.createECDH('secp256k1');
-    var bob = crypto.createECDH('secp256k1');
+    const crypto = require('crypto');
+    const alice = crypto.createECDH('secp256k1');
+    const bob = crypto.createECDH('secp256k1');
 
     // Note: This is a shortcut way to specify one of Alice's previous private
     // keys. It would be unwise to use such a predictable private key in a real
@@ -294,8 +294,8 @@ Example (obtaining a shared secret):
     // Bob uses a newly generated cryptographically strong pseudorandom key pair
     bob.generateKeys();
 
-    var alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
-    var bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
+    const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
+    const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
 
     // alice_secret and bob_secret should be the same shared secret value
     console.log(alice_secret === bob_secret);
@@ -535,20 +535,20 @@ algorithms.
 
 Example: this program that takes the sha256 sum of a file
 
-    var filename = process.argv[2];
-    var crypto = require('crypto');
-    var fs = require('fs');
+    const filename = process.argv[2];
+    const crypto = require('crypto');
+    const fs = require('fs');
 
-    var shasum = crypto.createHash('sha256');
+    const shasum = crypto.createHash('sha256');
 
-    var s = fs.ReadStream(filename);
-    s.on('data', function(d) {
+    const s = fs.ReadStream(filename);
+    s.on('data', (d) => {
       shasum.update(d);
     });
 
-    s.on('end', function() {
+    s.on('end', () => {
       var d = shasum.digest('hex');
-      console.log(d + '  ' + filename);
+      console.log(`${d}  ${filename}`);
     });
 
 ## crypto.createHmac(algorithm, key)
@@ -581,7 +581,7 @@ Returns an array with the names of the supported ciphers.
 
 Example:
 
-    var ciphers = crypto.getCiphers();
+    const ciphers = crypto.getCiphers();
     console.log(ciphers); // ['aes-128-cbc', 'aes-128-ccm', ...]
 
 ## crypto.getCurves()
@@ -590,7 +590,7 @@ Returns an array with the names of the supported elliptic curves.
 
 Example:
 
-    var curves = crypto.getCurves();
+    const curves = crypto.getCurves();
     console.log(curves); // ['secp256k1', 'secp384r1', ...]
 
 ## crypto.getDiffieHellman(group_name)
@@ -608,15 +608,15 @@ and communication time.
 
 Example (obtaining a shared secret):
 
-    var crypto = require('crypto');
-    var alice = crypto.getDiffieHellman('modp14');
-    var bob = crypto.getDiffieHellman('modp14');
+    const crypto = require('crypto');
+    const alice = crypto.getDiffieHellman('modp14');
+    const bob = crypto.getDiffieHellman('modp14');
 
     alice.generateKeys();
     bob.generateKeys();
 
-    var alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
-    var bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
+    const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
+    const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
 
     /* alice_secret and bob_secret should be the same */
     console.log(alice_secret == bob_secret);
@@ -627,7 +627,7 @@ Returns an array with the names of the supported hash algorithms.
 
 Example:
 
-    var hashes = crypto.getHashes();
+    const hashes = crypto.getHashes();
     console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...]
 
 ## crypto.pbkdf2(password, salt, iterations, keylen[, digest], callback)
@@ -711,7 +711,7 @@ NOTE: All paddings are defined in `constants` module.
 Generates cryptographically strong pseudo-random data. Usage:
 
     // async
-    crypto.randomBytes(256, function(ex, buf) {
+    crypto.randomBytes(256, (ex, buf) => {
       if (ex) throw ex;
       console.log('Have %d bytes of random data: %s', buf.length, buf);
     });
diff --git a/doc/api/debugger.markdown b/doc/api/debugger.markdown
index 7154b7ae50db13..77671b7a7f75b8 100644
--- a/doc/api/debugger.markdown
+++ b/doc/api/debugger.markdown
@@ -27,9 +27,9 @@ For example, suppose `myscript.js` looked like this:
     x = 5;
     setTimeout(function () {
       debugger;
-      console.log("world");
+      console.log('world');
     }, 1000);
-    console.log("hello");
+    console.log('hello');
 
 Then once the debugger is run, it will break on line 4.
 
@@ -46,15 +46,15 @@ Then once the debugger is run, it will break on line 4.
       1 x = 5;
       2 setTimeout(function () {
       3   debugger;
-      4   console.log("world");
+      4   console.log('world');
       5 }, 1000);
     debug> next
     break in /home/indutny/Code/git/indutny/myscript.js:4
       2 setTimeout(function () {
       3   debugger;
-      4   console.log("world");
+      4   console.log('world');
       5 }, 1000);
-      6 console.log("hello");
+      6 console.log('hello');
     debug> repl
     Press Ctrl + C to leave debug repl
     > x
@@ -65,9 +65,9 @@ Then once the debugger is run, it will break on line 4.
     < world
     break in /home/indutny/Code/git/indutny/myscript.js:5
       3   debugger;
-      4   console.log("world");
+      4   console.log('world');
       5 }, 1000);
-      6 console.log("hello");
+      6 console.log('hello');
       7
     debug> quit
     %
diff --git a/doc/api/dgram.markdown b/doc/api/dgram.markdown
index 71c59db3bf747c..996379a04283f3 100644
--- a/doc/api/dgram.markdown
+++ b/doc/api/dgram.markdown
@@ -9,14 +9,14 @@ Datagram sockets are available through `require('dgram')`.
 Important note: the behavior of [`dgram.Socket#bind()`][] has changed in v0.10
 and is always asynchronous now.  If you have code that looks like this:
 
-    var s = dgram.createSocket('udp4');
+    const s = dgram.createSocket('udp4');
     s.bind(1234);
     s.addMembership('224.0.0.114');
 
 You have to change it to this:
 
-    var s = dgram.createSocket('udp4');
-    s.bind(1234, function() {
+    const s = dgram.createSocket('udp4');
+    s.bind(1234, () => {
       s.addMembership('224.0.0.114');
     });
 
@@ -49,7 +49,7 @@ are created.
 Emitted when a new datagram is available on a socket.  `msg` is a `Buffer` and
 `rinfo` is an object with the sender's address information:
 
-    socket.on('message', function(msg, rinfo) {
+    socket.on('message', (msg, rinfo) => {
       console.log('Received %d bytes from %s:%d\n',
                   msg.length, rinfo.address, rinfo.port);
     });
@@ -92,24 +92,22 @@ binding a closed socket), an [`Error`][] may be thrown by this method.
 
 Example of a UDP server listening on port 41234:
 
-    var dgram = require("dgram");
+    const dgram = require('dgram');
 
-    var server = dgram.createSocket("udp4");
+    const server = dgram.createSocket('udp4');
 
-    server.on("error", function (err) {
-      console.log("server error:\n" + err.stack);
+    server.on('error', (err) => {
+      console.log(`server error:\n${err.stack}`);
       server.close();
     });
 
-    server.on("message", function (msg, rinfo) {
-      console.log("server got: " + msg + " from " +
-        rinfo.address + ":" + rinfo.port);
+    server.on('message', (msg, rinfo) => {
+      console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
     });
 
-    server.on("listening", function () {
+    server.on('listening', () => {
       var address = server.address();
-      console.log("server listening " +
-          address.address + ":" + address.port);
+      console.log(`server listening ${address.address}:${address.port}`);
     });
 
     server.bind(41234);
@@ -189,10 +187,10 @@ be calculated with respect to [byte length][] and not the character position.
 
 Example of sending a UDP packet to a random port on `localhost`;
 
-    var dgram = require('dgram');
-    var message = new Buffer("Some bytes");
-    var client = dgram.createSocket("udp4");
-    client.send(message, 0, message.length, 41234, "localhost", function(err) {
+    const dgram = require('dgram');
+    const message = new Buffer('Some bytes');
+    const client = dgram.createSocket('udp4');
+    client.send(message, 0, message.length, 41234, 'localhost', (err) => {
       client.close();
     });
 
diff --git a/doc/api/dns.markdown b/doc/api/dns.markdown
index ef68b93b8afabf..1b01f0ee1cead7 100644
--- a/doc/api/dns.markdown
+++ b/doc/api/dns.markdown
@@ -8,13 +8,13 @@ This module contains functions that belong to two different categories:
 
 1) Functions that use the underlying operating system facilities to perform
 name resolution, and that do not necessarily do any network communication.
-This category contains only one function: [`dns.lookup()`][]. __Developers looking
-to perform name resolution in the same way that other applications on the same
-operating system behave should use [`dns.lookup()`][].__
+This category contains only one function: [`dns.lookup()`][]. __Developers
+looking to perform name resolution in the same way that other applications on
+the same operating system behave should use [`dns.lookup()`][].__
 
 Here is an example that does a lookup of `www.google.com`.
 
-    var dns = require('dns');
+    const dns = require('dns');
 
     dns.lookup('www.google.com', function onLookup(err, addresses, family) {
       console.log('addresses:', addresses);
@@ -22,30 +22,29 @@ Here is an example that does a lookup of `www.google.com`.
 
 2) Functions that connect to an actual DNS server to perform name resolution,
 and that _always_ use the network to perform DNS queries. This category
-contains all functions in the `dns` module but [`dns.lookup()`][]. These functions
-do not use the same set of configuration files than what [`dns.lookup()`][] uses.
-For instance, _they do not use the configuration from `/etc/hosts`_. These
-functions should be used by developers who do not want to use the underlying
-operating system's facilities for name resolution, and instead want to
-_always_ perform DNS queries.
+contains all functions in the `dns` module but [`dns.lookup()`][]. These
+functions do not use the same set of configuration files than what
+[`dns.lookup()`][] uses. For instance, _they do not use the configuration from
+`/etc/hosts`_. These functions should be used by developers who do not want to
+use the underlying operating system's facilities for name resolution, and
+instead want to _always_ perform DNS queries.
 
 Here is an example which resolves `'www.google.com'` then reverse
 resolves the IP addresses which are returned.
 
-    var dns = require('dns');
+    const dns = require('dns');
 
-    dns.resolve4('www.google.com', function (err, addresses) {
+    dns.resolve4('www.google.com', (err, addresses) => {
       if (err) throw err;
 
-      console.log('addresses: ' + JSON.stringify(addresses));
+      console.log(`addresses: ${JSON.stringify(addresses)}`);
 
-      addresses.forEach(function (a) {
-        dns.reverse(a, function (err, hostnames) {
+      addresses.forEach((a) => {
+        dns.reverse(a, (err, hostnames) => {
           if (err) {
             throw err;
           }
-
-          console.log('reverse for ' + a + ': ' + JSON.stringify(hostnames));
+          console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`);
         });
       });
     });
@@ -164,16 +163,17 @@ records). `addresses` is an array of the canonical name records available for
 
 ## dns.resolveMx(hostname, callback)
 
-The same as [`dns.resolve()`][], but only for mail exchange queries (`MX` records).
+The same as [`dns.resolve()`][], but only for mail exchange queries
+(`MX` records).
 
 `addresses` is an array of MX records, each with a priority and an exchange
 attribute (e.g. `[{'priority': 10, 'exchange': 'mx.example.com'},...]`).
 
 ## dns.resolveNs(hostname, callback)
 
-The same as [`dns.resolve()`][], but only for name server records (`NS` records).
-`addresses` is an array of the name server records available for `hostname`
-(e.g., `['ns1.example.com', 'ns2.example.com']`).
+The same as [`dns.resolve()`][], but only for name server records
+(`NS` records). `addresses` is an array of the name server records available
+for `hostname` (e.g., `['ns1.example.com', 'ns2.example.com']`).
 
 ## dns.resolveSoa(hostname, callback)
 
@@ -271,20 +271,20 @@ on some operating systems (e.g FreeBSD 10.1).
 
 ## Implementation considerations
 
-Although [`dns.lookup()`][] and `dns.resolve*()/dns.reverse()` functions have the same
-goal of associating a network name with a network address (or vice versa),
-their behavior is quite different. These differences can have subtle but
+Although [`dns.lookup()`][] and `dns.resolve*()/dns.reverse()` functions have
+the same goal of associating a network name with a network address (or vice
+versa), their behavior is quite different. These differences can have subtle but
 significant consequences on the behavior of Node.js programs.
 
 ### dns.lookup
 
-Under the hood, [`dns.lookup()`][] uses the same operating system facilities as most
-other programs. For instance, [`dns.lookup()`][] will almost always resolve a given
-name the same way as the `ping` command. On most POSIX-like operating systems,
-the behavior of the [`dns.lookup()`][] function can be tweaked by changing settings
-in `nsswitch.conf(5)` and/or `resolv.conf(5)`, but be careful that changing
-these files will change the behavior of all other programs running on the same
-operating system.
+Under the hood, [`dns.lookup()`][] uses the same operating system facilities
+as most other programs. For instance, [`dns.lookup()`][] will almost always
+resolve a given name the same way as the `ping` command. On most POSIX-like
+operating systems, the behavior of the [`dns.lookup()`][] function can be
+tweaked by changing settings in `nsswitch.conf(5)` and/or `resolv.conf(5)`, but
+be careful that changing these files will change the behavior of all other
+programs running on the same operating system.
 
 Though the call will be asynchronous from JavaScript's perspective, it is
 implemented as a synchronous call to `getaddrinfo(3)` that runs on libuv's
@@ -299,10 +299,10 @@ setting the 'UV_THREADPOOL_SIZE' environment variable to a value greater than
 
 ### dns.resolve, functions starting with dns.resolve and dns.reverse
 
-These functions are implemented quite differently than [`dns.lookup()`][]. They do
-not use `getaddrinfo(3)` and they _always_ perform a DNS query on the network.
-This network communication is always done asynchronously, and does not use
-libuv's threadpool.
+These functions are implemented quite differently than [`dns.lookup()`][]. They
+do not use `getaddrinfo(3)` and they _always_ perform a DNS query on the
+network. This network communication is always done asynchronously, and does not
+use libuv's threadpool.
 
 As a result, these functions cannot have the same negative impact on other
 processing that happens on libuv's threadpool that [`dns.lookup()`][] can have.
diff --git a/doc/api/domain.markdown b/doc/api/domain.markdown
index 16854d46acce6c..410a74498ddeaa 100644
--- a/doc/api/domain.markdown
+++ b/doc/api/domain.markdown
@@ -48,15 +48,15 @@ For example, this is not a good idea:
 // XXX WARNING!  BAD IDEA!
 
 var d = require('domain').create();
-d.on('error', function(er) {
+d.on('error', (er) => {
   // The error won't crash the process, but what it does is worse!
   // Though we've prevented abrupt process restarting, we are leaking
   // resources like crazy if this ever happens.
   // This is no better than process.on('uncaughtException')!
   console.log('error, but oh well', er.message);
 });
-d.run(function() {
-  require('http').createServer(function(req, res) {
+d.run(() => {
+  require('http').createServer((req, res) => {
     handleRequest(req, res);
   }).listen(PORT);
 });
@@ -69,8 +69,8 @@ appropriately, and handle errors with much greater safety.
 ```javascript
 // Much better!
 
-var cluster = require('cluster');
-var PORT = +process.env.PORT || 1337;
+const cluster = require('cluster');
+const PORT = +process.env.PORT || 1337;
 
 if (cluster.isMaster) {
   // In real life, you'd probably use more than just 2 workers,
@@ -88,7 +88,7 @@ if (cluster.isMaster) {
   cluster.fork();
   cluster.fork();
 
-  cluster.on('disconnect', function(worker) {
+  cluster.on('disconnect', (worker) => {
     console.error('disconnect!');
     cluster.fork();
   });
@@ -98,14 +98,14 @@ if (cluster.isMaster) {
   //
   // This is where we put our bugs!
 
-  var domain = require('domain');
+  const domain = require('domain');
 
   // See the cluster documentation for more details about using
   // worker processes to serve requests.  How it works, caveats, etc.
 
-  var server = require('http').createServer(function(req, res) {
+  const server = require('http').createServer((req, res) => {
     var d = domain.create();
-    d.on('error', function(er) {
+    d.on('error', (er) => {
       console.error('error', er.stack);
 
       // Note: we're in dangerous territory!
@@ -115,7 +115,7 @@ if (cluster.isMaster) {
 
       try {
         // make sure we close down within 30 seconds
-        var killtimer = setTimeout(function() {
+        var killtimer = setTimeout(() => {
           process.exit(1);
         }, 30000);
         // But don't keep the process open just for that!
@@ -146,7 +146,7 @@ if (cluster.isMaster) {
     d.add(res);
 
     // Now run the handler function in the domain.
-    d.run(function() {
+    d.run(() => {
       handleRequest(req, res);
     });
   });
@@ -159,7 +159,7 @@ function handleRequest(req, res) {
   switch(req.url) {
     case '/error':
       // We do some async stuff, and then...
-      setTimeout(function() {
+      setTimeout(() => {
         // Whoops!
         flerb.bark();
       });
@@ -229,18 +229,20 @@ For example:
 
 ```
 // create a top-level domain for the server
-var serverDomain = domain.create();
+const domain = require('domain');
+const http = require('http');
+const serverDomain = domain.create();
 
-serverDomain.run(function() {
+serverDomain.run(() => {
   // server is created in the scope of serverDomain
-  http.createServer(function(req, res) {
+  http.createServer((req, res) => {
     // req and res are also created in the scope of serverDomain
     // however, we'd prefer to have a separate domain for each request.
     // create it first thing, and add req and res to it.
     var reqd = domain.create();
     reqd.add(req);
     reqd.add(res);
-    reqd.on('error', function(er) {
+    reqd.on('error', (er) => {
       console.error('Error', er, req.url);
       try {
         res.writeHead(500);
@@ -281,14 +283,16 @@ This is the most basic way to use a domain.
 Example:
 
 ```
-var d = domain.create();
-d.on('error', function(er) {
+const domain = require('domain');
+const fs = require('fs');
+const d = domain.create();
+d.on('error', (er) => {
   console.error('Caught error!', er);
 });
-d.run(function() {
-  process.nextTick(function() {
-    setTimeout(function() { // simulating some various async stuff
-      fs.open('non-existent file', 'r', function(er, fd) {
+d.run(() => {
+  process.nextTick(() => {
+    setTimeout(() => { // simulating some various async stuff
+      fs.open('non-existent file', 'r', (er, fd) => {
         if (er) throw er;
         // proceed...
       });
@@ -341,7 +345,7 @@ thrown will be routed to the domain's `'error'` event.
 
 #### Example
 
-    var d = domain.create();
+    const d = domain.create();
 
     function readSomeFile(filename, cb) {
       fs.readFile(filename, 'utf8', d.bind(function(er, data) {
@@ -350,7 +354,7 @@ thrown will be routed to the domain's `'error'` event.
       }));
     }
 
-    d.on('error', function(er) {
+    d.on('error', (er) => {
       // an error occurred somewhere.
       // if we throw it now, it will crash the program
       // with the normal line number and stack message.
@@ -370,7 +374,7 @@ with a single error handler in a single place.
 
 #### Example
 
-    var d = domain.create();
+    const d = domain.create();
 
     function readSomeFile(filename, cb) {
       fs.readFile(filename, 'utf8', d.intercept(function(data) {
@@ -386,7 +390,7 @@ with a single error handler in a single place.
       }));
     }
 
-    d.on('error', function(er) {
+    d.on('error', (er) => {
       // an error occurred somewhere.
       // if we throw it now, it will crash the program
       // with the normal line number and stack message.
diff --git a/doc/api/errors.markdown b/doc/api/errors.markdown
index a12489fdc14123..48c1bc574d1bcd 100644
--- a/doc/api/errors.markdown
+++ b/doc/api/errors.markdown
@@ -47,12 +47,12 @@ it will crash the process as an unhandled exception unless [domains][] are
 employed appropriately or [`process.on('uncaughtException')`][] has a handler.
 
 ```javascript
-var net = require('net');
+const net = require('net');
 
-var connection = net.connect('localhost');
+const connection = net.connect('localhost');
 
 // adding an 'error' event handler to a stream:
-connection.on('error', function(err) {
+connection.on('error', (err) => {
   // if the connection is reset by the server, or if it can't
   // connect at all, or on any sort of error encountered by
   // the connection, the error will be sent here.
@@ -67,11 +67,11 @@ provided by Node.js -- even user created event emitters and streams will throw
 errors when no error handlers are attached. An example:
 
 ```javascript
-var EventEmitter = require('events');
+const EventEmitter = require('events');
 
-var ee = new EventEmitter();
+const ee = new EventEmitter();
 
-setImmediate(function() {
+setImmediate(() => {
   // this will crash the process because no 'error' event
   // handler has been added.
   ee.emit('error', new Error('This will crash'));
@@ -92,14 +92,14 @@ at least **one** argument -- `error` -- that will either be `null` (if no error
 was encountered) or an `Error` instance.  For instance:
 
 ```javascript
-var fs = require('fs');
+const fs = require('fs');
 
 fs.readFile('/some/file/that/does-not-exist', function nodeStyleCallback(err, data) {
   console.log(err)  // Error: ENOENT
   console.log(data) // undefined / null
 });
 
-fs.readFile('/some/file/that/does-exist', function(err, data) {
+fs.readFile('/some/file/that/does-exist', (err, data) => {
   console.log(err)  // null
   console.log(data) // <Buffer: ba dd ca fe>
 })
@@ -111,10 +111,10 @@ inside their node style callback:
 
 ```javascript
 // THIS WILL NOT WORK:
-var fs = require('fs');
+const fs = require('fs');
 
 try {
-  fs.readFile('/some/file/that/does-not-exist', function(err, data) {
+  fs.readFile('/some/file/that/does-not-exist', (err, data) => {
     // mistaken assumption: throwing here...
     if (err) {
       throw err;
@@ -240,7 +240,7 @@ calls a JavaScript function, the frame representing the `cheetahify` call will *
 be present in stacktraces:
 
 ```javascript
-var cheetahify = require('./native-binding.node');
+const cheetahify = require('./native-binding.node');
 
 function makeFaster() {
   // cheetahify *synchronously* calls speedy.
@@ -331,7 +331,7 @@ program.
 
 ```javascript
 try {
-  require("vm").runInThisContext("binary ! isNotOk");
+  require('vm').runInThisContext('binary ! isNotOk');
 } catch(err) {
   // err will be a SyntaxError
 }
diff --git a/doc/api/events.markdown b/doc/api/events.markdown
index 92bec13632683a..02617b10e8dc5c 100644
--- a/doc/api/events.markdown
+++ b/doc/api/events.markdown
@@ -24,7 +24,7 @@ attached to.
 Use `require('events')` to access the EventEmitter class.
 
 ```javascript
-var EventEmitter = require('events');
+const EventEmitter = require('events');
 ```
 
 When an `EventEmitter` instance experiences an error, the typical action is
@@ -107,7 +107,7 @@ This can be useful to increment/decrement max listeners to avoid the warning
 while not being irresponsible and setting a too big number.
 
     emitter.setMaxListeners(emitter.getMaxListeners() + 1);
-    emitter.once('event', function () {
+    emitter.once('event', () => {
       // do stuff
       emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));
     });
@@ -122,7 +122,7 @@ Returns the number of listeners listening to the `type` of event.
 
 Returns a copy of the array of listeners for the specified event.
 
-    server.on('connection', function (stream) {
+    server.on('connection', (stream) => {
       console.log('someone connected!');
     });
     console.log(util.inspect(server.listeners('connection'))); // [ [Function] ]
@@ -134,7 +134,7 @@ No checks are made to see if the `listener` has already been added. Multiple
 calls passing the same combination of `event` and `listener` will result in the
 `listener` being added multiple times.
 
-    server.on('connection', function (stream) {
+    server.on('connection', (stream) => {
       console.log('someone connected!');
     });
 
@@ -146,7 +146,7 @@ Adds a **one time** listener for the event. This listener is
 invoked only the next time the event is fired, after which
 it is removed.
 
-    server.once('connection', function (stream) {
+    server.once('connection', (stream) => {
       console.log('Ah, we have our first user!');
     });
 
diff --git a/doc/api/fs.markdown b/doc/api/fs.markdown
index 82f10d9ca16e79..6b505dcadfa313 100644
--- a/doc/api/fs.markdown
+++ b/doc/api/fs.markdown
@@ -18,16 +18,16 @@ You can use try/catch to handle exceptions or allow them to bubble up.
 
 Here is an example of the asynchronous version:
 
-    var fs = require('fs');
+    const fs = require('fs');
 
-    fs.unlink('/tmp/hello', function (err) {
+    fs.unlink('/tmp/hello', (err) => {
       if (err) throw err;
       console.log('successfully deleted /tmp/hello');
     });
 
 Here is the synchronous version:
 
-    var fs = require('fs');
+    const fs = require('fs');
 
     fs.unlinkSync('/tmp/hello');
     console.log('successfully deleted /tmp/hello');
@@ -35,23 +35,23 @@ Here is the synchronous version:
 With the asynchronous methods there is no guaranteed ordering. So the
 following is prone to error:
 
-    fs.rename('/tmp/hello', '/tmp/world', function (err) {
+    fs.rename('/tmp/hello', '/tmp/world', (err) => {
       if (err) throw err;
       console.log('renamed complete');
     });
-    fs.stat('/tmp/world', function (err, stats) {
+    fs.stat('/tmp/world', (err, stats) => {
       if (err) throw err;
-      console.log('stats: ' + JSON.stringify(stats));
+      console.log(`stats: ${JSON.stringify(stats)}`);
     });
 
 It could be that `fs.stat` is executed before `fs.rename`.
 The correct way to do this is to chain the callbacks.
 
-    fs.rename('/tmp/hello', '/tmp/world', function (err) {
+    fs.rename('/tmp/hello', '/tmp/world', (err) => {
       if (err) throw err;
-      fs.stat('/tmp/world', function (err, stats) {
+      fs.stat('/tmp/world', (err, stats) => {
         if (err) throw err;
-        console.log('stats: ' + JSON.stringify(stats));
+        console.log(`stats: ${JSON.stringify(stats)}`);
       });
     });
 
@@ -240,7 +240,7 @@ Asynchronously append data to a file, creating the file if it does not yet exist
 
 Example:
 
-    fs.appendFile('message.txt', 'data to append', function (err) {
+    fs.appendFile('message.txt', 'data to append', (err) => {
       if (err) throw err;
       console.log('The "data to append" was appended to file!');
     });
@@ -355,8 +355,8 @@ If `options` is a string, then it specifies the encoding.
 Test whether or not the given path exists by checking with the file system.
 Then call the `callback` argument with either true or false.  Example:
 
-    fs.exists('/etc/passwd', function (exists) {
-      console.log(exists ? "it's there" : 'no passwd!');
+    fs.exists('/etc/passwd', (exists) => {
+      console.log(exists ? 'it\'s there' : 'no passwd!');
     });
 
 `fs.exists()` should not be used to check if a file exists before calling
@@ -579,7 +579,7 @@ Synchronous readdir(3). Returns an array of filenames excluding `'.'` and
 
 Asynchronously reads the entire contents of a file. Example:
 
-    fs.readFile('/etc/passwd', function (err, data) {
+    fs.readFile('/etc/passwd', (err, data) => {
       if (err) throw err;
       console.log(data);
     });
@@ -623,7 +623,7 @@ resolution or avoid additional `fs.stat` calls for known real paths.
 Example:
 
     var cache = {'/etc':'/private/etc'};
-    fs.realpath('/etc/passwd', cache, function (err, resolvedPath) {
+    fs.realpath('/etc/passwd', cache, (err, resolvedPath) => {
       if (err) throw err;
       console.log(resolvedPath);
     });
@@ -790,10 +790,10 @@ Windows.  Even on supported platforms, `filename` is not always guaranteed to
 be provided. Therefore, don't assume that `filename` argument is always
 provided in the callback, and have some fallback logic if it is null.
 
-    fs.watch('somedir', function (event, filename) {
-      console.log('event is: ' + event);
+    fs.watch('somedir', (event, filename) => {
+      console.log(`event is: ${event}`);
       if (filename) {
-        console.log('filename provided: ' + filename);
+        console.log(`filename provided: ${filename}`);
       } else {
         console.log('filename not provided');
       }
@@ -814,9 +814,9 @@ target should be polled in milliseconds. The default is
 The `listener` gets two arguments the current stat object and the previous
 stat object:
 
-    fs.watchFile('message.text', function (curr, prev) {
-      console.log('the current mtime is: ' + curr.mtime);
-      console.log('the previous mtime was: ' + prev.mtime);
+    fs.watchFile('message.text', (curr, prev) => {
+      console.log(`the current mtime is: ${curr.mtime}`);
+      console.log(`the previous mtime was: ${prev.mtime}`);
     });
 
 These stat objects are instances of `fs.Stat`.
@@ -900,7 +900,7 @@ to `'utf8'`.
 
 Example:
 
-    fs.writeFile('message.txt', 'Hello Node.js', function (err) {
+    fs.writeFile('message.txt', 'Hello Node.js', (err) => {
       if (err) throw err;
       console.log('It\'s saved!');
     });
diff --git a/doc/api/http.markdown b/doc/api/http.markdown
index fb2cbae8914ee6..6562a469a73bdb 100644
--- a/doc/api/http.markdown
+++ b/doc/api/http.markdown
@@ -64,10 +64,10 @@ a `'close'` event or a special `'agentRemove'` event. This means that if
 you intend to keep one HTTP request open for a long time and don't
 want it to stay in the pool you can do something along the lines of:
 
-    http.get(options, function(res) {
+    http.get(options, (res) => {
       // Do stuff
-    }).on("socket", function (socket) {
-      socket.emit("agentRemove");
+    }).on('socket', (socket) => {
+      socket.emit('agentRemove');
     });
 
 Alternatively, you could just opt out of pooling entirely using
@@ -78,7 +78,7 @@ Alternatively, you could just opt out of pooling entirely using
       port: 80,
       path: '/',
       agent: false  // create a new agent just for this one request
-    }, function (res) {
+    }, (res) => {
       // Do stuff with response
     })
 
@@ -103,7 +103,7 @@ of these values set to their respective defaults.
 To configure any of them, you must create your own [`http.Agent`][] object.
 
 ```javascript
-var http = require('http');
+const http = require('http');
 var keepAliveAgent = new http.Agent({ keepAlive: true });
 options.agent = keepAliveAgent;
 http.request(options, onResponseCallback);
@@ -202,19 +202,19 @@ their connections closed.
 
 A client server pair that show you how to listen for the `'connect'` event.
 
-    var http = require('http');
-    var net = require('net');
-    var url = require('url');
+    const http = require('http');
+    const net = require('net');
+    const url = require('url');
 
     // Create an HTTP tunneling proxy
-    var proxy = http.createServer(function (req, res) {
+    var proxy = http.createServer( (req, res) => {
       res.writeHead(200, {'Content-Type': 'text/plain'});
       res.end('okay');
     });
-    proxy.on('connect', function(req, cltSocket, head) {
+    proxy.on('connect', (req, cltSocket, head) => {
       // connect to an origin server
-      var srvUrl = url.parse('http://' + req.url);
-      var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, function() {
+      var srvUrl = url.parse(`http://${req.url}`);
+      var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, () => {
         cltSocket.write('HTTP/1.1 200 Connection Established\r\n' +
                         'Proxy-agent: Node.js-Proxy\r\n' +
                         '\r\n');
@@ -225,7 +225,7 @@ A client server pair that show you how to listen for the `'connect'` event.
     });
 
     // now that proxy is running
-    proxy.listen(1337, '127.0.0.1', function() {
+    proxy.listen(1337, '127.0.0.1', () => {
 
       // make a request to a tunneling proxy
       var options = {
@@ -238,7 +238,7 @@ A client server pair that show you how to listen for the `'connect'` event.
       var req = http.request(options);
       req.end();
 
-      req.on('connect', function(res, socket, head) {
+      req.on('connect', (res, socket, head) => {
         console.log('got connected!');
 
         // make a request over an HTTP tunnel
@@ -246,10 +246,10 @@ A client server pair that show you how to listen for the `'connect'` event.
                      'Host: www.google.com:80\r\n' +
                      'Connection: close\r\n' +
                      '\r\n');
-        socket.on('data', function(chunk) {
+        socket.on('data', (chunk) => {
           console.log(chunk.toString());
         });
-        socket.on('end', function() {
+        socket.on('end', () => {
           proxy.close();
         });
       });
@@ -292,14 +292,14 @@ their connections closed.
 
 A client server pair that show you how to listen for the `'upgrade'` event.
 
-    var http = require('http');
+    const http = require('http');
 
     // Create an HTTP server
-    var srv = http.createServer(function (req, res) {
+    var srv = http.createServer( (req, res) => {
       res.writeHead(200, {'Content-Type': 'text/plain'});
       res.end('okay');
     });
-    srv.on('upgrade', function(req, socket, head) {
+    srv.on('upgrade', (req, socket, head) => {
       socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
                    'Upgrade: WebSocket\r\n' +
                    'Connection: Upgrade\r\n' +
@@ -309,7 +309,7 @@ A client server pair that show you how to listen for the `'upgrade'` event.
     });
 
     // now that server is running
-    srv.listen(1337, '127.0.0.1', function() {
+    srv.listen(1337, '127.0.0.1', () => {
 
       // make a request
       var options = {
@@ -324,7 +324,7 @@ A client server pair that show you how to listen for the `'upgrade'` event.
       var req = http.request(options);
       req.end();
 
-      req.on('upgrade', function(res, socket, upgradeHead) {
+      req.on('upgrade', (res, socket, upgradeHead) => {
         console.log('got upgraded!');
         socket.end();
         process.exit(0);
@@ -606,7 +606,7 @@ emit trailers, with a list of the header fields in its value. E.g.,
     response.writeHead(200, { 'Content-Type': 'text/plain',
                               'Trailer': 'Content-MD5' });
     response.write(fileData);
-    response.addTrailers({'Content-MD5': "7895bf4b8828b55ceaf47747b4bca667"});
+    response.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'});
     response.end();
 
 Attempting to set a trailer field name that contains invalid characters will
@@ -649,7 +649,7 @@ Removes a header that's queued for implicit sending.
 
 Example:
 
-    response.removeHeader("Content-Encoding");
+    response.removeHeader('Content-Encoding');
 
 ### response.sendDate
 
@@ -667,11 +667,11 @@ here if you need to send multiple headers with the same name.
 
 Example:
 
-    response.setHeader("Content-Type", "text/html");
+    response.setHeader('Content-Type', 'text/html');
 
 or
 
-    response.setHeader("Set-Cookie", ["type=ninja", "language=javascript"]);
+    response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
 
 Attempting to set a header field name that contains invalid characters will
 result in a [`TypeError`][] being thrown.
@@ -964,12 +964,12 @@ is that it sets the method to GET and calls `req.end()` automatically.
 
 Example:
 
-    http.get("http://www.google.com/index.html", function(res) {
-      console.log("Got response: " + res.statusCode);
+    http.get('http://www.google.com/index.html', (res) => {
+      console.log(`Got response: ${res.statusCode}`);
       // consume response body
       res.resume();
-    }).on('error', function(e) {
-      console.log("Got error: " + e.message);
+    }).on('error', (e) => {
+      console.log(`Got error: ${e.message}`);
     });
 
 ## http.globalAgent
@@ -1037,20 +1037,20 @@ Example:
       }
     };
 
-    var req = http.request(options, function(res) {
-      console.log('STATUS: ' + res.statusCode);
-      console.log('HEADERS: ' + JSON.stringify(res.headers));
+    var req = http.request(options, (res) => {
+      console.log(`STATUS: ${res.statusCode}`);
+      console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
       res.setEncoding('utf8');
-      res.on('data', function (chunk) {
-        console.log('BODY: ' + chunk);
+      res.on('data', (chunk) => {
+        console.log(`BODY: ${chunk}`);
       });
-      res.on('end', function() {
+      res.on('end', () => {
         console.log('No more data in response.')
       })
     });
 
-    req.on('error', function(e) {
-      console.log('problem with request: ' + e.message);
+    req.on('error', (e) => {
+      console.log(`problem with request: ${e.message}`);
     });
 
     // write data to request body
diff --git a/doc/api/https.markdown b/doc/api/https.markdown
index aab07b9ce35be3..93416633747fb4 100644
--- a/doc/api/https.markdown
+++ b/doc/api/https.markdown
@@ -32,31 +32,31 @@ automatically added to the `'request'` event.
 Example:
 
     // curl -k https://localhost:8000/
-    var https = require('https');
-    var fs = require('fs');
+    const https = require('https');
+    const fs = require('fs');
 
-    var options = {
+    const options = {
       key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
       cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
     };
 
-    https.createServer(options, function (req, res) {
+    https.createServer(options, (req, res) => {
       res.writeHead(200);
-      res.end("hello world\n");
+      res.end('hello world\n');
     }).listen(8000);
 
 Or
 
-    var https = require('https');
-    var fs = require('fs');
+    const https = require('https');
+    const fs = require('fs');
 
-    var options = {
+    const options = {
       pfx: fs.readFileSync('server.pfx')
     };
 
-    https.createServer(options, function (req, res) {
+    https.createServer(options, (req, res) => {
       res.writeHead(200);
-      res.end("hello world\n");
+      res.end('hello world\n');
     }).listen(8000);
 
 ### server.close([callback])
@@ -78,17 +78,17 @@ automatically parsed with [`url.parse()`][].
 
 Example:
 
-    var https = require('https');
+    const https = require('https');
 
-    https.get('https://encrypted.google.com/', function(res) {
-      console.log("statusCode: ", res.statusCode);
-      console.log("headers: ", res.headers);
+    https.get('https://encrypted.google.com/', (res) => {
+      console.log('statusCode: ', res.statusCode);
+      console.log('headers: ', res.headers);
 
-      res.on('data', function(d) {
+      res.on('data', (d) => {
         process.stdout.write(d);
       });
 
-    }).on('error', function(e) {
+    }).on('error', (e) => {
       console.error(e);
     });
 
@@ -107,7 +107,7 @@ All options from [`http.request()`][] are valid.
 
 Example:
 
-    var https = require('https');
+    const https = require('https');
 
     var options = {
       hostname: 'encrypted.google.com',
@@ -116,17 +116,17 @@ Example:
       method: 'GET'
     };
 
-    var req = https.request(options, function(res) {
-      console.log("statusCode: ", res.statusCode);
-      console.log("headers: ", res.headers);
+    var req = https.request(options, (res) => {
+      console.log('statusCode: ', res.statusCode);
+      console.log('headers: ', res.headers);
 
-      res.on('data', function(d) {
+      res.on('data', (d) => {
         process.stdout.write(d);
       });
     });
     req.end();
 
-    req.on('error', function(e) {
+    req.on('error', (e) => {
       console.error(e);
     });
 
@@ -192,7 +192,7 @@ Example:
     };
     options.agent = new https.Agent(options);
 
-    var req = https.request(options, function(res) {
+    var req = https.request(options, (res) => {
       ...
     }
 
@@ -210,7 +210,7 @@ Example:
       agent: false
     };
 
-    var req = https.request(options, function(res) {
+    var req = https.request(options, (res) => {
       ...
     }
 
diff --git a/doc/api/modules.markdown b/doc/api/modules.markdown
index 00c1c77915c93f..aa1f0b074e5043 100644
--- a/doc/api/modules.markdown
+++ b/doc/api/modules.markdown
@@ -10,13 +10,12 @@ in one-to-one correspondence.  As an example, `foo.js` loads the module
 
 The contents of `foo.js`:
 
-    var circle = require('./circle.js');
-    console.log( 'The area of a circle of radius 4 is '
-               + circle.area(4));
+    const circle = require('./circle.js');
+    console.log( `The area of a circle of radius 4 is ${circle.area(4)}`);
 
 The contents of `circle.js`:
 
-    var PI = Math.PI;
+    const PI = Math.PI;
 
     exports.area = function (r) {
       return PI * r * r;
@@ -40,9 +39,9 @@ instead of `exports`.
 
 Below, `bar.js` makes use of the `square` module, which exports a constructor:
 
-    var square = require('./square.js');
+    const square = require('./square.js');
     var mySquare = square(2);
-    console.log('The area of my square is ' + mySquare.area());
+    console.log(`The area of my square is ${mySquare.area()}`);
 
 The `square` module is defined in `square.js`:
 
@@ -233,7 +232,7 @@ Consider this situation:
 
     console.log('a starting');
     exports.done = false;
-    var b = require('./b.js');
+    const b = require('./b.js');
     console.log('in a, b.done = %j', b.done);
     exports.done = true;
     console.log('a done');
@@ -242,7 +241,7 @@ Consider this situation:
 
     console.log('b starting');
     exports.done = false;
-    var a = require('./a.js');
+    const a = require('./a.js');
     console.log('in b, a.done = %j', a.done);
     exports.done = true;
     console.log('b done');
@@ -250,8 +249,8 @@ Consider this situation:
 `main.js`:
 
     console.log('main starting');
-    var a = require('./a.js');
-    var b = require('./b.js');
+    const a = require('./a.js');
+    const b = require('./b.js');
     console.log('in main, a.done=%j, b.done=%j', a.done, b.done);
 
 When `main.js` loads `a.js`, then `a.js` in turn loads `b.js`.  At that
@@ -425,20 +424,20 @@ which is probably not what you want to do.
 
 For example suppose we were making a module called `a.js`
 
-    var EventEmitter = require('events');
+    const EventEmitter = require('events');
 
     module.exports = new EventEmitter();
 
     // Do some work, and after some time emit
     // the 'ready' event from the module itself.
-    setTimeout(function() {
+    setTimeout(() => {
       module.exports.emit('ready');
     }, 1000);
 
 Then in another file we could do
 
-    var a = require('./a');
-    a.on('ready', function() {
+    const a = require('./a');
+    a.on('ready', () => {
       console.log('module a is ready');
     });
 
@@ -448,13 +447,13 @@ done in any callbacks.  This does not work:
 
 x.js:
 
-    setTimeout(function() {
-      module.exports = { a: "hello" };
+    setTimeout(() => {
+      module.exports = { a: 'hello' };
     }, 0);
 
 y.js:
 
-    var x = require('./x');
+    const x = require('./x');
     console.log(x.a);
 
 #### exports alias
diff --git a/doc/api/net.markdown b/doc/api/net.markdown
index 32d2218982db35..7e898596f5a18e 100644
--- a/doc/api/net.markdown
+++ b/doc/api/net.markdown
@@ -45,14 +45,14 @@ Returns an object with three properties, e.g.
 
 Example:
 
-    var server = net.createServer(function (socket) {
-      socket.end("goodbye\n");
+    var server = net.createServer((socket) => {
+      socket.end('goodbye\n');
     });
 
     // grab a random port.
-    server.listen(function() {
+    server.listen(() => {
       address = server.address();
-      console.log("opened server on %j", address);
+      console.log('opened server on %j', address);
     });
 
 Don't call `server.address()` until the `'listening'` event has been emitted.
@@ -184,10 +184,10 @@ One issue some users run into is getting `EADDRINUSE` errors. This means that
 another server is already running on the requested port. One way of handling this
 would be to wait a second and then try again. This can be done with
 
-    server.on('error', function (e) {
+    server.on('error', (e) => {
       if (e.code == 'EADDRINUSE') {
         console.log('Address in use, retrying...');
-        setTimeout(function () {
+        setTimeout(() => {
           server.close();
           server.listen(PORT, HOST);
         }, 1000);
@@ -512,24 +512,23 @@ The `connectListener` parameter will be added as a listener for the
 
 Here is an example of a client of the previously described echo server:
 
-    var net = require('net');
-    var client = net.connect({port: 8124},
-        function() { //'connect' listener
+    const net = require('net');
+    const client = net.connect({port: 8124}, () => { //'connect' listener
       console.log('connected to server!');
       client.write('world!\r\n');
     });
-    client.on('data', function(data) {
+    client.on('data', (data) => {
       console.log(data.toString());
       client.end();
     });
-    client.on('end', function() {
+    client.on('end', () => {
       console.log('disconnected from server');
     });
 
 To connect on the socket `/tmp/echo.sock` the second line would just be
 changed to
 
-    var client = net.connect({path: '/tmp/echo.sock'});
+    const client = net.connect({path: '/tmp/echo.sock'});
 
 ## net.connect(path[, connectListener])
 
@@ -562,24 +561,24 @@ The `connectListener` parameter will be added as a listener for the
 
 Here is an example of a client of the previously described echo server:
 
-    var net = require('net');
-    var client = net.connect({port: 8124},
-        function() { //'connect' listener
+    const net = require('net');
+    const client = net.connect({port: 8124},
+        () => { //'connect' listener
       console.log('connected to server!');
       client.write('world!\r\n');
     });
-    client.on('data', function(data) {
+    client.on('data', (data) => {
       console.log(data.toString());
       client.end();
     });
-    client.on('end', function() {
+    client.on('end', () => {
       console.log('disconnected from server');
     });
 
 To connect on the socket `/tmp/echo.sock` the second line would just be
 changed to
 
-    var client = net.connect({path: '/tmp/echo.sock'});
+    const client = net.connect({path: '/tmp/echo.sock'});
 
 ## net.createConnection(path[, connectListener])
 
@@ -624,16 +623,16 @@ original process. To begin reading data from a paused socket, call [`resume()`][
 Here is an example of an echo server which listens for connections
 on port 8124:
 
-    var net = require('net');
-    var server = net.createServer(function(c) { //'connection' listener
+    const net = require('net');
+    const server = net.createServer((c) => { //'connection' listener
       console.log('client connected');
-      c.on('end', function() {
+      c.on('end', () => {
         console.log('client disconnected');
       });
       c.write('hello\r\n');
       c.pipe(c);
     });
-    server.listen(8124, function() { //'listening' listener
+    server.listen(8124, () => { //'listening' listener
       console.log('server bound');
     });
 
@@ -644,7 +643,7 @@ Test this by using `telnet`:
 To listen on the socket `/tmp/echo.sock` the third line from the last would
 just be changed to
 
-    server.listen('/tmp/echo.sock', function() { //'listening' listener
+    server.listen('/tmp/echo.sock', () => { //'listening' listener
 
 Use `nc` to connect to a UNIX domain socket server:
 
diff --git a/doc/api/process.markdown b/doc/api/process.markdown
index 73724b39b96ff2..987bca9f657a23 100644
--- a/doc/api/process.markdown
+++ b/doc/api/process.markdown
@@ -29,9 +29,9 @@ implicitly by the event loop draining.
 
 Example of listening for `'exit'`:
 
-    process.on('exit', function(code) {
+    process.on('exit', (code) => {
       // do *NOT* do this
-      setTimeout(function() {
+      setTimeout(() => {
         console.log('This will not run');
       }, 0);
       console.log('About to exit with code:', code);
@@ -71,11 +71,11 @@ event tells you when the list of unhandled rejections shrinks.
 For example using the rejection detection hooks in order to keep a map of all
 the rejected promise reasons at a given time:
 
-    var unhandledRejections = new Map();
-    process.on('unhandledRejection', function(reason, p) {
+    const unhandledRejections = new Map();
+    process.on('unhandledRejection', (reason, p) => {
       unhandledRejections.set(p, reason);
     });
-    process.on('rejectionHandled', function(p) {
+    process.on('rejectionHandled', (p) => {
       unhandledRejections.delete(p);
     });
 
@@ -93,11 +93,11 @@ a stack trace and exit) will not occur.
 
 Example of listening for `'uncaughtException'`:
 
-    process.on('uncaughtException', function(err) {
-      console.log('Caught exception: ' + err);
+    process.on('uncaughtException', (err) => {
+      console.log(`Caught exception: ${err}`);
     });
 
-    setTimeout(function() {
+    setTimeout(() => {
       console.log('This will still run.');
     }, 500);
 
@@ -138,7 +138,7 @@ instance).
 
 Here is an example that logs every unhandled rejection to the console
 
-    process.on('unhandledRejection', function(reason, p) {
+    process.on('unhandledRejection', (reason, p) => {
         console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);
         // application specific logging, throwing an error, or other logic here
     });
@@ -146,8 +146,8 @@ Here is an example that logs every unhandled rejection to the console
 For example, here is a rejection that will trigger the `'unhandledRejection'`
 event:
 
-    somePromise.then(function(res) {
-      return reportToUser(JSON.pasre(res)); // note the typo
+    somePromise.then((res) => {
+      return reportToUser(JSON.parse(res)); // note the typo
     }); // no `.catch` or `.then`
 
 Here is an example of a coding pattern that will also trigger
@@ -226,7 +226,7 @@ Example of listening for `SIGINT`:
     // Start reading from stdin so we don't exit.
     process.stdin.resume();
 
-    process.on('SIGINT', function() {
+    process.on('SIGINT', () => {
       console.log('Got SIGINT.  Press Control-D to exit.');
     });
 
@@ -285,8 +285,8 @@ An array containing the command line arguments.  The first element will be
 next elements will be any additional command line arguments.
 
     // print process.argv
-    process.argv.forEach(function(val, index, array) {
-      console.log(index + ': ' + val);
+    process.argv.forEach((val, index, array) => {
+      console.log(`${index}: ${val}`);
     });
 
 This will generate:
@@ -302,13 +302,13 @@ This will generate:
 
 Changes the current working directory of the process or throws an exception if that fails.
 
-    console.log('Starting directory: ' + process.cwd());
+    console.log(`Starting directory: ${process.cwd()}`);
     try {
       process.chdir('/tmp');
-      console.log('New directory: ' + process.cwd());
+      console.log(`New directory: ${process.cwd()}`);
     }
     catch (err) {
-      console.log('chdir: ' + err);
+      console.log(`chdir: ${err}`);
     }
 
 ## process.config
@@ -350,7 +350,7 @@ If `process.connected` is false, it is no longer possible to send messages.
 
 Returns the current working directory of the process.
 
-    console.log('Current directory: ' + process.cwd());
+    console.log(`Current directory: ${process.cwd()}`);
 
 ## process.disconnect()
 
@@ -450,7 +450,7 @@ Gets the effective group identity of the process. (See getegid(2).)
 This is the numerical group id, not the group name.
 
     if (process.getegid) {
-      console.log('Current gid: ' + process.getegid());
+      console.log(`Current gid: ${process.getegid()}`);
     }
 
 
@@ -463,7 +463,7 @@ Gets the effective user identity of the process. (See geteuid(2).)
 This is the numerical userid, not the username.
 
     if (process.geteuid) {
-      console.log('Current uid: ' + process.geteuid());
+      console.log(`Current uid: ${process.geteuid()}`);
     }
 
 ## process.getgid()
@@ -475,7 +475,7 @@ Gets the group identity of the process. (See getgid(2).)
 This is the numerical group id, not the group name.
 
     if (process.getgid) {
-      console.log('Current gid: ' + process.getgid());
+      console.log(`Current gid: ${process.getgid()}`);
     }
 
 ## process.getgroups()
@@ -495,7 +495,7 @@ Gets the user identity of the process. (See getuid(2).)
 This is the numerical userid, not the username.
 
     if (process.getuid) {
-      console.log('Current uid: ' + process.getuid());
+      console.log(`Current uid: ${process.getuid()}`);
     }
 
 ## process.hrtime()
@@ -511,7 +511,7 @@ a diff reading, useful for benchmarks and measuring intervals:
     var time = process.hrtime();
     // [ 1800216, 25 ]
 
-    setTimeout(function() {
+    setTimeout(() => {
       var diff = process.hrtime(time);
       // [ 1, 552 ]
 
@@ -556,11 +556,11 @@ something other than kill the target process.
 
 Example of sending a signal to yourself:
 
-    process.on('SIGHUP', function() {
+    process.on('SIGHUP', () => {
       console.log('Got SIGHUP signal.');
     });
 
-    setTimeout(function() {
+    setTimeout(() => {
       console.log('Exiting.');
       process.exit(0);
     }, 100);
@@ -584,7 +584,7 @@ As with `require.main`, it will be `undefined` if there was no entry script.
 Returns an object describing the memory usage of the Node.js process
 measured in bytes.
 
-    var util = require('util');
+    const util = require('util');
 
     console.log(util.inspect(process.memoryUsage()));
 
@@ -609,7 +609,7 @@ efficient.  It runs before any additional I/O events (including
 timers) fire in subsequent ticks of the event loop.
 
     console.log('start');
-    process.nextTick(function() {
+    process.nextTick(() => {
       console.log('nextTick callback');
     });
     console.log('scheduled');
@@ -625,7 +625,7 @@ but before any I/O has occurred.
     function MyThing(options) {
       this.setupOptions(options);
 
-      process.nextTick(function() {
+      process.nextTick(() => {
         this.startDoingStuff();
       }.bind(this));
     }
@@ -677,14 +677,14 @@ happening, just like a `while(true);` loop.
 
 The PID of the process.
 
-    console.log('This process is pid ' + process.pid);
+    console.log(`This process is pid ${process.pid}`);
 
 ## process.platform
 
 What platform you're running on:
 `'darwin'`, `'freebsd'`, `'linux'`, `'sunos'` or `'win32'`
 
-    console.log('This platform is ' + process.platform);
+    console.log(`This platform is ${process.platform}`);
 
 ## process.release
 
@@ -738,13 +738,13 @@ This accepts either a numerical ID or a groupname string. If a groupname
 is specified, this method blocks while resolving it to a numerical ID.
 
     if (process.getegid && process.setegid) {
-      console.log('Current gid: ' + process.getegid());
+      console.log(`Current gid: ${process.getegid()}`);
       try {
         process.setegid(501);
-        console.log('New gid: ' + process.getegid());
+        console.log(`New gid: ${process.getegid()}`);
       }
       catch (err) {
-        console.log('Failed to set gid: ' + err);
+        console.log(`Failed to set gid: ${err}`);
       }
     }
 
@@ -758,13 +758,13 @@ This accepts either a numerical ID or a username string.  If a username
 is specified, this method blocks while resolving it to a numerical ID.
 
     if (process.geteuid && process.seteuid) {
-      console.log('Current uid: ' + process.geteuid());
+      console.log(`Current uid: ${process.geteuid()}`);
       try {
         process.seteuid(501);
-        console.log('New uid: ' + process.geteuid());
+        console.log(`New uid: ${process.geteuid()}`);
       }
       catch (err) {
-        console.log('Failed to set uid: ' + err);
+        console.log(`Failed to set uid: ${err}`);
       }
     }
 
@@ -778,13 +778,13 @@ a numerical ID or a groupname string. If a groupname is specified, this method
 blocks while resolving it to a numerical ID.
 
     if (process.getgid && process.setgid) {
-      console.log('Current gid: ' + process.getgid());
+      console.log(`Current gid: ${process.getgid()}`);
       try {
         process.setgid(501);
-        console.log('New gid: ' + process.getgid());
+        console.log(`New gid: ${process.getgid()}`);
       }
       catch (err) {
-        console.log('Failed to set gid: ' + err);
+        console.log(`Failed to set gid: ${err}`);
       }
     }
 
@@ -808,13 +808,13 @@ a numerical ID or a username string.  If a username is specified, this method
 blocks while resolving it to a numerical ID.
 
     if (process.getuid && process.setuid) {
-      console.log('Current uid: ' + process.getuid());
+      console.log(`Current uid: ${process.getuid()}`);
       try {
         process.setuid(501);
-        console.log('New uid: ' + process.getuid());
+        console.log(`New uid: ${process.getuid()}`);
       }
       catch (err) {
-        console.log('Failed to set uid: ' + err);
+        console.log(`Failed to set uid: ${err}`);
       }
     }
 
@@ -836,14 +836,14 @@ Example of opening standard input and listening for both events:
 
     process.stdin.setEncoding('utf8');
 
-    process.stdin.on('readable', function() {
+    process.stdin.on('readable', () => {
       var chunk = process.stdin.read();
       if (chunk !== null) {
-        process.stdout.write('data: ' + chunk);
+        process.stdout.write(`data: ${chunk}`);
       }
     });
 
-    process.stdin.on('end', function() {
+    process.stdin.on('end', () => {
       process.stdout.write('end');
     });
 
@@ -865,7 +865,7 @@ A `Writable Stream` to `stdout` (on fd `1`).
 For example, a `console.log` equivalent could look like this:
 
     console.log = function(msg) {
-      process.stdout.write(msg + '\n');
+      process.stdout.write(`${msg}\n`);
     };
 
 `process.stderr` and `process.stdout` are unlike other streams in Node.js in
@@ -909,11 +909,11 @@ Sets or reads the process's file mode creation mask. Child processes inherit
 the mask from the parent process. Returns the old mask if `mask` argument is
 given, otherwise returns the current mask.
 
-    var oldmask, newmask = 0022;
-
-    oldmask = process.umask(newmask);
-    console.log('Changed umask from: ' + oldmask.toString(8) +
-                ' to ' + newmask.toString(8));
+    const newmask = 0o022;
+    const oldmask = process.umask(newmask);
+    console.log(
+      `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}`
+    );
 
 
 ## process.uptime()
@@ -924,7 +924,7 @@ Number of seconds Node.js has been running.
 
 A compiled-in property that exposes `NODE_VERSION`.
 
-    console.log('Version: ' + process.version);
+    console.log(`Version: ${process.version}`);
 
 ## process.versions
 
diff --git a/doc/api/readline.markdown b/doc/api/readline.markdown
index cdf424339ed06a..5d98f501f68c65 100644
--- a/doc/api/readline.markdown
+++ b/doc/api/readline.markdown
@@ -9,16 +9,16 @@ Note that once you've invoked this module, your Node.js program will not
 terminate until you've closed the interface. Here's how to allow your
 program to gracefully exit:
 
-    var readline = require('readline');
+    const readline = require('readline');
 
-    var rl = readline.createInterface({
+    const rl = readline.createInterface({
       input: process.stdin,
       output: process.stdout
     });
 
-    rl.question("What do you think of Node.js? ", function(answer) {
+    rl.question('What do you think of Node.js? ', (answer) => {
       // TODO: Log the answer in a database
-      console.log("Thank you for your valuable feedback:", answer);
+      console.log('Thank you for your valuable feedback:', answer);
 
       rl.close();
     });
@@ -66,8 +66,8 @@ nothing is displayed.
 
 Example usage:
 
-    interface.question('What is your favorite food?', function(answer) {
-      console.log('Oh, so your favorite food is ' + answer);
+    interface.question('What is your favorite food?', (answer) => {
+      console.log(`Oh, so your favorite food is ${answer}`);
     });
 
 ### rl.resume()
@@ -117,8 +117,8 @@ user hits enter, or return. This is a good hook to listen for user input.
 
 Example of listening for `'line'`:
 
-    rl.on('line', function (cmd) {
-      console.log('You just typed: '+cmd);
+    rl.on('line', (cmd) => {
+      console.log(`You just typed: ${cmd}`);
     });
 
 ### Event: 'pause'
@@ -132,7 +132,7 @@ Also emitted whenever the `input` stream is not paused and receives the
 
 Example of listening for `'pause'`:
 
-    rl.on('pause', function() {
+    rl.on('pause', () => {
       console.log('Readline paused.');
     });
 
@@ -144,7 +144,7 @@ Emitted whenever the `input` stream is resumed.
 
 Example of listening for `'resume'`:
 
-    rl.on('resume', function() {
+    rl.on('resume', () => {
       console.log('Readline resumed.');
     });
 
@@ -161,7 +161,7 @@ background.
 
 Example of listening for `SIGCONT`:
 
-    rl.on('SIGCONT', function() {
+    rl.on('SIGCONT', () => {
       // `prompt` will automatically resume the stream
       rl.prompt();
     });
@@ -176,8 +176,8 @@ stream receives a `SIGINT`, `pause` will be triggered.
 
 Example of listening for `SIGINT`:
 
-    rl.on('SIGINT', function() {
-      rl.question('Are you sure you want to exit?', function(answer) {
+    rl.on('SIGINT', () => {
+      rl.question('Are you sure you want to exit?', (answer) => {
         if (answer.match(/^y(es)?$/i)) rl.pause();
       });
     });
@@ -200,7 +200,7 @@ before the program was sent to the background.
 
 Example of listening for `SIGTSTP`:
 
-    rl.on('SIGTSTP', function() {
+    rl.on('SIGTSTP', () => {
       // This will override SIGTSTP and prevent the program from going to the
       // background.
       console.log('Caught SIGTSTP.');
@@ -211,13 +211,13 @@ Example of listening for `SIGTSTP`:
 Here's an example of how to use all these together to craft a tiny command
 line interface:
 
-    var readline = require('readline'),
-        rl = readline.createInterface(process.stdin, process.stdout);
+    const readline = require('readline');
+    const rl = readline.createInterface(process.stdin, process.stdout);
 
     rl.setPrompt('OHAI> ');
     rl.prompt();
 
-    rl.on('line', function(line) {
+    rl.on('line', (line) => {
       switch(line.trim()) {
         case 'hello':
           console.log('world!');
@@ -227,7 +227,7 @@ line interface:
           break;
       }
       rl.prompt();
-    }).on('close', function() {
+    }).on('close', () => {
       console.log('Have a great day!');
       process.exit(0);
     });
@@ -277,7 +277,7 @@ Example:
 
     function completer(line) {
       var completions = '.help .error .exit .quit .q'.split(' ')
-      var hits = completions.filter(function(c) { return c.indexOf(line) == 0 })
+      var hits = completions.filter((c) => { return c.indexOf(line) == 0 })
       // show all completions if none found
       return [hits.length ? hits : completions, line]
     }
@@ -291,8 +291,8 @@ Also `completer` can be run in async mode if it accepts two arguments:
 `createInterface` is commonly used with [`process.stdin`][] and
 [`process.stdout`][] in order to accept user input:
 
-    var readline = require('readline');
-    var rl = readline.createInterface({
+    const readline = require('readline');
+    const rl = readline.createInterface({
       input: process.stdin,
       output: process.stdout
     });
diff --git a/doc/api/repl.markdown b/doc/api/repl.markdown
index d5d4ec62ec7549..99e9d0e26d8720 100644
--- a/doc/api/repl.markdown
+++ b/doc/api/repl.markdown
@@ -85,8 +85,8 @@ a variable to the REPL explicitly by assigning it to the `context` object
 associated with each `REPLServer`.  For example:
 
     // repl_test.js
-    var repl = require('repl'),
-        msg = 'message';
+    const repl = require('repl');
+    var msg = 'message';
 
     repl.start('> ').context.m = msg;
 
@@ -152,7 +152,7 @@ to signal `'end'` on the `input` stream.
 
 Example of listening for `exit`:
 
-    replServer.on('exit', function () {
+    replServer.on('exit', () => {
       console.log('Got "exit" event from repl!');
       process.exit();
     });
@@ -173,7 +173,7 @@ Example of listening for `reset`:
     someExtension.extend(r.context);
 
     // When a new context is created extend it as well.
-    replServer.on('reset', function (context) {
+    replServer.on('reset', (context) => {
       console.log('repl has a new context');
       someExtension.extend(context);
     });
@@ -196,13 +196,13 @@ If a function is provided instead of an object for `cmd`, it is treated as the
 Example of defining a command:
 
     // repl_test.js
-    var repl = require('repl');
+    const repl = require('repl');
 
     var replServer = repl.start();
     replServer.defineCommand('sayhello', {
       help: 'Say hello',
       action: function(name) {
-        this.write('Hello, ' + name + '!\n');
+        this.write(`Hello, ${name}!\n');
         this.displayPrompt();
       }
     });
@@ -277,9 +277,9 @@ will share the same global object but will have unique I/O.
 
 Here is an example that starts a REPL on stdin, a Unix socket, and a TCP socket:
 
-    var net = require('net'),
-        repl = require('repl'),
-        connections = 0;
+    const net = require('net');
+    const repl = require('repl');
+    var connections = 0;
 
     repl.start({
       prompt: 'Node.js via stdin> ',
@@ -287,24 +287,24 @@ Here is an example that starts a REPL on stdin, a Unix socket, and a TCP socket:
       output: process.stdout
     });
 
-    net.createServer(function (socket) {
+    net.createServer((socket) => {
       connections += 1;
       repl.start({
         prompt: 'Node.js via Unix socket> ',
         input: socket,
         output: socket
-      }).on('exit', function() {
+      }).on('exit', () => {
         socket.end();
       })
     }).listen('/tmp/node-repl-sock');
 
-    net.createServer(function (socket) {
+    net.createServer((socket) => {
       connections += 1;
       repl.start({
         prompt: 'Node.js via TCP socket> ',
         input: socket,
         output: socket
-      }).on('exit', function() {
+      }).on('exit', () => {
         socket.end();
       });
     }).listen(5001);
diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown
index b76ef0093e1847..e874b6f8b8d129 100644
--- a/doc/api/stream.markdown
+++ b/doc/api/stream.markdown
@@ -50,9 +50,9 @@ Almost all Node.js programs, no matter how simple, use Streams in some
 way. Here is an example of using Streams in an Node.js program:
 
 ```javascript
-var http = require('http');
+const http = require('http');
 
-var server = http.createServer(function (req, res) {
+var server = http.createServer( (req, res) => {
   // req is an http.IncomingMessage, which is a Readable Stream
   // res is an http.ServerResponse, which is a Writable Stream
 
@@ -62,18 +62,18 @@ var server = http.createServer(function (req, res) {
   req.setEncoding('utf8');
 
   // Readable streams emit 'data' events once a listener is added
-  req.on('data', function (chunk) {
+  req.on('data', (chunk) => {
     body += chunk;
   });
 
   // the end event tells you that you have entire body
-  req.on('end', function () {
+  req.on('end', () => {
     try {
       var data = JSON.parse(body);
     } catch (er) {
       // uh oh!  bad json!
       res.statusCode = 400;
-      return res.end('error: ' + er.message);
+      return res.end(`error: ${er.message}`);
     }
 
     // write back something interesting to the user:
@@ -176,7 +176,7 @@ possible, this is the best way to do so.
 
 ```javascript
 var readable = getReadableStreamSomehow();
-readable.on('data', function(chunk) {
+readable.on('data', (chunk) => {
   console.log('got %d bytes of data', chunk.length);
 });
 ```
@@ -191,10 +191,10 @@ or by calling `read()` repeatedly until you get to the end.
 
 ```javascript
 var readable = getReadableStreamSomehow();
-readable.on('data', function(chunk) {
+readable.on('data', (chunk) => {
   console.log('got %d bytes of data', chunk.length);
 });
-readable.on('end', function() {
+readable.on('end', () => {
   console.log('there will be no more data.');
 });
 ```
@@ -216,7 +216,7 @@ hadn't already.
 
 ```javascript
 var readable = getReadableStreamSomehow();
-readable.on('readable', function() {
+readable.on('readable', () => {
   // there is some data to read now
 });
 ```
@@ -234,12 +234,12 @@ In the former case, `.read()` will return that data. In the latter case,
 is an empty file:
 
 ```javascript
-var fs = require('fs');
+const fs = require('fs');
 var rr = fs.createReadStream('foo.txt');
-rr.on('readable', function() {
+rr.on('readable', () => {
   console.log('readable:', rr.read());
 });
-rr.on('end', function() {
+rr.on('end', () => {
   console.log('end');
 });
 ```
@@ -280,11 +280,11 @@ available will remain in the internal buffer.
 
 ```javascript
 var readable = getReadableStreamSomehow();
-readable.on('data', function(chunk) {
+readable.on('data', (chunk) => {
   console.log('got %d bytes of data', chunk.length);
   readable.pause();
   console.log('there will be no more data for 1 second');
-  setTimeout(function() {
+  setTimeout(() => {
     console.log('now data will start flowing again');
     readable.resume();
   }, 1000);
@@ -335,7 +335,7 @@ end.
 
 ```javascript
 reader.pipe(writer, { end: false });
-reader.on('end', function() {
+reader.on('end', () => {
   writer.end('Goodbye\n');
 });
 ```
@@ -366,7 +366,7 @@ drained.
 
 ```javascript
 var readable = getReadableStreamSomehow();
-readable.on('readable', function() {
+readable.on('readable', () => {
   var chunk;
   while (null !== (chunk = readable.read())) {
     console.log('got %d bytes of data', chunk.length);
@@ -395,7 +395,7 @@ data.
 ```javascript
 var readable = getReadableStreamSomehow();
 readable.resume();
-readable.on('end', function() {
+readable.on('end', () => {
   console.log('got to the end, but did not read anything');
 });
 ```
@@ -420,7 +420,7 @@ as strings, always use this method.
 ```javascript
 var readable = getReadableStreamSomehow();
 readable.setEncoding('utf8');
-readable.on('data', function(chunk) {
+readable.on('data', (chunk) => {
   assert.equal(typeof chunk, 'string');
   console.log('got %d characters of string data', chunk.length);
 });
@@ -443,7 +443,7 @@ var writable = fs.createWriteStream('file.txt');
 // All the data from readable goes into 'file.txt',
 // but only for the first second
 readable.pipe(writable);
-setTimeout(function() {
+setTimeout(() => {
   console.log('stop writing to file.txt');
   readable.unpipe(writable);
   console.log('manually close the file stream');
@@ -471,7 +471,7 @@ for Stream Implementors, below.)
 // Pull off a header delimited by \n\n
 // use unshift() if we get too much
 // Call the callback with (error, header, stream)
-var StringDecoder = require('string_decoder').StringDecoder;
+const StringDecoder = require('string_decoder').StringDecoder;
 function parseHeader(stream, callback) {
   stream.on('error', callback);
   stream.on('readable', onReadable);
@@ -528,12 +528,12 @@ as a convenience for interacting with old Node.js programs and libraries.
 For example:
 
 ```javascript
-var OldReader = require('./old-api-module.js').OldReader;
-var oreader = new OldReader;
-var Readable = require('stream').Readable;
-var myReader = new Readable().wrap(oreader);
+const OldReader = require('./old-api-module.js').OldReader;
+const Readable = require('stream').Readable;
+const oreader = new OldReader;
+const myReader = new Readable().wrap(oreader);
 
-myReader.on('readable', function() {
+myReader.on('readable', () => {
   myReader.read(); // etc.
 });
 ```
@@ -615,10 +615,10 @@ to the underlying system, this event is emitted.
 ```javascript
 var writer = getWritableStreamSomehow();
 for (var i = 0; i < 100; i ++) {
-  writer.write('hello, #' + i + '!\n');
+  writer.write('hello, #${i}!\n');
 }
 writer.end('this is the end\n');
-writer.on('finish', function() {
+writer.on('finish', () => {
   console.error('all writes are now complete.');
 });
 ```
@@ -633,7 +633,7 @@ stream, adding this writable to its set of destinations.
 ```javascript
 var writer = getWritableStreamSomehow();
 var reader = getReadableStreamSomehow();
-writer.on('pipe', function(src) {
+writer.on('pipe', (src) => {
   console.error('something is piping into the writer');
   assert.equal(src, reader);
 });
@@ -650,7 +650,7 @@ readable stream, removing this writable from its set of destinations.
 ```javascript
 var writer = getWritableStreamSomehow();
 var reader = getReadableStreamSomehow();
-writer.on('unpipe', function(src) {
+writer.on('unpipe', (src) => {
   console.error('something has stopped piping into the writer');
   assert.equal(src, reader);
 });
@@ -955,8 +955,8 @@ This is a basic example of a Readable stream.  It emits the numerals
 from 1 to 1,000,000 in ascending order, and then ends.
 
 ```javascript
-var Readable = require('stream').Readable;
-var util = require('util');
+const Readable = require('stream').Readable;
+const util = require('util');
 util.inherits(Counter, Readable);
 
 function Counter(opt) {
@@ -995,8 +995,8 @@ below for a better implementation.
 // Using Readable directly for this is sub-optimal.  See the
 // alternative example below under the Transform section.
 
-var Readable = require('stream').Readable;
-var util = require('util');
+const Readable = require('stream').Readable;
+const util = require('util');
 
 util.inherits(SimpleProtocol, Readable);
 
@@ -1012,13 +1012,13 @@ function SimpleProtocol(source, options) {
   this._source = source;
 
   var self = this;
-  source.on('end', function() {
+  source.on('end', () => {
     self.push(null);
   });
 
   // give it a kick whenever the source is readable
   // read(0) will not consume any bytes
-  source.on('readable', function() {
+  source.on('readable', () => {
     self.read(0);
   });
 
@@ -1210,8 +1210,8 @@ would be piped into the parser, which is a more idiomatic Node.js stream
 approach.
 
 ```javascript
-var util = require('util');
-var Transform = require('stream').Transform;
+const util = require('util');
+const Transform = require('stream').Transform;
 util.inherits(SimpleProtocol, Transform);
 
 function SimpleProtocol(options) {
@@ -1518,10 +1518,10 @@ For example, consider the following code:
 
 ```javascript
 // WARNING!  BROKEN!
-net.createServer(function(socket) {
+net.createServer((socket) => {
 
   // we add an 'end' method, but never consume the data
-  socket.on('end', function() {
+  socket.on('end', () => {
     // It will never get here.
     socket.end('I got your message (but didnt read it)\n');
   });
@@ -1538,9 +1538,9 @@ start the flow of data:
 
 ```javascript
 // Workaround
-net.createServer(function(socket) {
+net.createServer((socket) => {
 
-  socket.on('end', function() {
+  socket.on('end', () => {
     socket.end('I got your message (but didnt read it)\n');
   });
 
@@ -1589,9 +1589,9 @@ respectively. These options can be used to implement parsers and
 serializers with Transform streams.
 
 ```javascript
-var util = require('util');
-var StringDecoder = require('string_decoder').StringDecoder;
-var Transform = require('stream').Transform;
+const util = require('util');
+const StringDecoder = require('string_decoder').StringDecoder;
+const Transform = require('stream').Transform;
 util.inherits(JSONParseStream, Transform);
 
 // Gets \n-delimited JSON string data, and emits the parsed objects
diff --git a/doc/api/string_decoder.markdown b/doc/api/string_decoder.markdown
index b58bcd2cf422c9..8bcba2cfbd51e9 100644
--- a/doc/api/string_decoder.markdown
+++ b/doc/api/string_decoder.markdown
@@ -6,13 +6,13 @@ To use this module, do `require('string_decoder')`. StringDecoder decodes a
 buffer to a string. It is a simple interface to `buffer.toString()` but provides
 additional support for utf8.
 
-    var StringDecoder = require('string_decoder').StringDecoder;
-    var decoder = new StringDecoder('utf8');
+    const StringDecoder = require('string_decoder').StringDecoder;
+    const decoder = new StringDecoder('utf8');
 
-    var cent = new Buffer([0xC2, 0xA2]);
+    const cent = new Buffer([0xC2, 0xA2]);
     console.log(decoder.write(cent));
 
-    var euro = new Buffer([0xE2, 0x82, 0xAC]);
+    const euro = new Buffer([0xE2, 0x82, 0xAC]);
     console.log(decoder.write(euro));
 
 ## Class: StringDecoder
diff --git a/doc/api/synopsis.markdown b/doc/api/synopsis.markdown
index 347b22e3cad284..4a051013c4a6e1 100644
--- a/doc/api/synopsis.markdown
+++ b/doc/api/synopsis.markdown
@@ -5,9 +5,9 @@
 An example of a [web server][] written with Node.js which responds with
 `'Hello World'`:
 
-    var http = require('http');
+    const http = require('http');
 
-    http.createServer(function (request, response) {
+    http.createServer( (request, response) => {
       response.writeHead(200, {'Content-Type': 'text/plain'});
       response.end('Hello World\n');
     }).listen(8124);
diff --git a/doc/api/tls.markdown b/doc/api/tls.markdown
index f7fbf1ee72a948..92946b65351f92 100644
--- a/doc/api/tls.markdown
+++ b/doc/api/tls.markdown
@@ -243,11 +243,11 @@ established after addition of event listener.
 Here's an example for using TLS session resumption:
 
     var tlsSessionStore = {};
-    server.on('newSession', function(id, data, cb) {
+    server.on('newSession', (id, data, cb) => {
       tlsSessionStore[id.toString('hex')] = data;
       cb();
     });
-    server.on('resumeSession', function(id, cb) {
+    server.on('resumeSession', (id, cb) => {
       cb(null, tlsSessionStore[id.toString('hex')] || null);
     });
 
@@ -615,10 +615,10 @@ The `callback` parameter will be added as a listener for the
 
 Here is an example of a client of echo server as described previously:
 
-    var tls = require('tls');
-    var fs = require('fs');
+    const tls = require('tls');
+    const fs = require('fs');
 
-    var options = {
+    const options = {
       // These are necessary only if using the client certificate authentication
       key: fs.readFileSync('client-key.pem'),
       cert: fs.readFileSync('client-cert.pem'),
@@ -627,40 +627,40 @@ Here is an example of a client of echo server as described previously:
       ca: [ fs.readFileSync('server-cert.pem') ]
     };
 
-    var socket = tls.connect(8000, options, function() {
+    var socket = tls.connect(8000, options, () => {
       console.log('client connected',
                   socket.authorized ? 'authorized' : 'unauthorized');
       process.stdin.pipe(socket);
       process.stdin.resume();
     });
     socket.setEncoding('utf8');
-    socket.on('data', function(data) {
+    socket.on('data', (data) => {
       console.log(data);
     });
-    socket.on('end', function() {
+    socket.on('end', () => {
       server.close();
     });
 
 Or
 
-    var tls = require('tls');
-    var fs = require('fs');
+    const tls = require('tls');
+    const fs = require('fs');
 
-    var options = {
+    const options = {
       pfx: fs.readFileSync('client.pfx')
     };
 
-    var socket = tls.connect(8000, options, function() {
+    var socket = tls.connect(8000, options, () => {
       console.log('client connected',
                   socket.authorized ? 'authorized' : 'unauthorized');
       process.stdin.pipe(socket);
       process.stdin.resume();
     });
     socket.setEncoding('utf8');
-    socket.on('data', function(data) {
+    socket.on('data', (data) => {
       console.log(data);
     });
-    socket.on('end', function() {
+    socket.on('end', () => {
       server.close();
     });
 
@@ -856,10 +856,10 @@ automatically set as a listener for the [`'secureConnection'`][] event.  The
 
 Here is a simple example echo server:
 
-    var tls = require('tls');
-    var fs = require('fs');
+    const tls = require('tls');
+    const fs = require('fs');
 
-    var options = {
+    const options = {
       key: fs.readFileSync('server-key.pem'),
       cert: fs.readFileSync('server-cert.pem'),
 
@@ -870,23 +870,23 @@ Here is a simple example echo server:
       ca: [ fs.readFileSync('client-cert.pem') ]
     };
 
-    var server = tls.createServer(options, function(socket) {
+    var server = tls.createServer(options, (socket) => {
       console.log('server connected',
                   socket.authorized ? 'authorized' : 'unauthorized');
-      socket.write("welcome!\n");
+      socket.write('welcome!\n');
       socket.setEncoding('utf8');
       socket.pipe(socket);
     });
-    server.listen(8000, function() {
+    server.listen(8000, () => {
       console.log('server bound');
     });
 
 Or
 
-    var tls = require('tls');
-    var fs = require('fs');
+    const tls = require('tls');
+    const fs = require('fs');
 
-    var options = {
+    const options = {
       pfx: fs.readFileSync('server.pfx'),
 
       // This is necessary only if using the client certificate authentication.
@@ -894,14 +894,14 @@ Or
 
     };
 
-    var server = tls.createServer(options, function(socket) {
+    var server = tls.createServer(options, (socket) => {
       console.log('server connected',
                   socket.authorized ? 'authorized' : 'unauthorized');
-      socket.write("welcome!\n");
+      socket.write('welcome!\n');
       socket.setEncoding('utf8');
       socket.pipe(socket);
     });
-    server.listen(8000, function() {
+    server.listen(8000, () => {
       console.log('server bound');
     });
 You can test this server by connecting to it with `openssl s_client`:
diff --git a/doc/api/tty.markdown b/doc/api/tty.markdown
index 251742a0e1b89b..f01cedd702da9a 100644
--- a/doc/api/tty.markdown
+++ b/doc/api/tty.markdown
@@ -45,9 +45,9 @@ ever created (and only when `isatty(1)` is true).
 Emitted by `refreshSize()` when either of the `columns` or `rows` properties
 has changed.
 
-    process.stdout.on('resize', function() {
+    process.stdout.on('resize', () => {
       console.log('screen size has changed!');
-      console.log(process.stdout.columns + 'x' + process.stdout.rows);
+      console.log(`${process.stdout.columns}x${process.stdout.rows}`);
     });
 
 ### ws.columns
diff --git a/doc/api/util.markdown b/doc/api/util.markdown
index 03386aefb5b78d..4574ae452b231b 100644
--- a/doc/api/util.markdown
+++ b/doc/api/util.markdown
@@ -53,7 +53,7 @@ comma.  For example, `NODE_DEBUG=fs,net,tls`.
 
 Marks that a method should not be used any more.
 
-    var util = require('util');
+    const util = require('util');
 
     exports.puts = util.deprecate(function() {
       for (var i = 0, len = arguments.length; i < len; ++i) {
@@ -123,8 +123,8 @@ prototype of `constructor` will be set to a new object created from
 As an additional convenience, `superConstructor` will be accessible
 through the `constructor.super_` property.
 
-    var util = require("util");
-    var EventEmitter = require("events");
+    const util = require('util');
+    const EventEmitter = require('events');
 
     function MyStream() {
         EventEmitter.call(this);
@@ -133,7 +133,7 @@ through the `constructor.super_` property.
     util.inherits(MyStream, EventEmitter);
 
     MyStream.prototype.write = function(data) {
-        this.emit("data", data);
+        this.emit('data', data);
     }
 
     var stream = new MyStream();
@@ -141,10 +141,10 @@ through the `constructor.super_` property.
     console.log(stream instanceof EventEmitter); // true
     console.log(MyStream.super_ === EventEmitter); // true
 
-    stream.on("data", function(data) {
-        console.log('Received data: "' + data + '"');
+    stream.on('data', (data) => {
+      console.log(`Received data: "${data}"`);
     })
-    stream.write("It works!"); // Received data: "It works!"
+    stream.write('It works!'); // Received data: "It works!"
 
 ## util.inspect(object[, options])
 
@@ -168,7 +168,7 @@ formatted string:
 
 Example of inspecting all properties of the `util` object:
 
-    var util = require('util');
+    const util = require('util');
 
     console.log(util.inspect(util, { showHidden: true, depth: null }));
 
@@ -207,11 +207,11 @@ There are also `bold`, `italic`, `underline` and `inverse` codes.
 Objects also may define their own `inspect(depth)` function which `util.inspect()`
 will invoke and use the result of when inspecting the object:
 
-    var util = require('util');
+    const util = require('util');
 
     var obj = { name: 'nate' };
     obj.inspect = function(depth) {
-      return '{' + this.name + '}';
+      return `{${this.name}}`;
     };
 
     util.inspect(obj);
@@ -237,7 +237,7 @@ Internal alias for [`Array.isArray`][].
 
 Returns `true` if the given "object" is an `Array`. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     util.isArray([])
       // true
@@ -252,7 +252,7 @@ Returns `true` if the given "object" is an `Array`. `false` otherwise.
 
 Returns `true` if the given "object" is a `Boolean`. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     util.isBoolean(1)
       // false
@@ -269,7 +269,7 @@ Use `Buffer.isBuffer()` instead.
 
 Returns `true` if the given "object" is a `Buffer`. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     util.isBuffer({ length: 0 })
       // false
@@ -284,7 +284,7 @@ Returns `true` if the given "object" is a `Buffer`. `false` otherwise.
 
 Returns `true` if the given "object" is a `Date`. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     util.isDate(new Date())
       // true
@@ -299,7 +299,7 @@ Returns `true` if the given "object" is a `Date`. `false` otherwise.
 
 Returns `true` if the given "object" is an [`Error`][]. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     util.isError(new Error())
       // true
@@ -314,7 +314,7 @@ Returns `true` if the given "object" is an [`Error`][]. `false` otherwise.
 
 Returns `true` if the given "object" is a `Function`. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     function Foo() {}
     var Bar = function() {};
@@ -332,7 +332,7 @@ Returns `true` if the given "object" is a `Function`. `false` otherwise.
 
 Returns `true` if the given "object" is strictly `null`. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     util.isNull(0)
       // false
@@ -347,7 +347,7 @@ Returns `true` if the given "object" is strictly `null`. `false` otherwise.
 
 Returns `true` if the given "object" is `null` or `undefined`. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     util.isNullOrUndefined(0)
       // false
@@ -362,7 +362,7 @@ Returns `true` if the given "object" is `null` or `undefined`. `false` otherwise
 
 Returns `true` if the given "object" is a `Number`. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     util.isNumber(false)
       // false
@@ -380,7 +380,7 @@ Returns `true` if the given "object" is a `Number`. `false` otherwise.
 Returns `true` if the given "object" is strictly an `Object` __and__ not a
 `Function`. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     util.isObject(5)
       // false
@@ -397,7 +397,7 @@ Returns `true` if the given "object" is strictly an `Object` __and__ not a
 
 Returns `true` if the given "object" is a primitive type. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     util.isPrimitive(5)
       // true
@@ -424,7 +424,7 @@ Returns `true` if the given "object" is a primitive type. `false` otherwise.
 
 Returns `true` if the given "object" is a `RegExp`. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     util.isRegExp(/some regexp/)
       // true
@@ -439,7 +439,7 @@ Returns `true` if the given "object" is a `RegExp`. `false` otherwise.
 
 Returns `true` if the given "object" is a `String`. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     util.isString('')
       // true
@@ -456,7 +456,7 @@ Returns `true` if the given "object" is a `String`. `false` otherwise.
 
 Returns `true` if the given "object" is a `Symbol`. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     util.isSymbol(5)
       // false
@@ -471,7 +471,7 @@ Returns `true` if the given "object" is a `Symbol`. `false` otherwise.
 
 Returns `true` if the given "object" is `undefined`. `false` otherwise.
 
-    var util = require('util');
+    const util = require('util');
 
     var foo;
     util.isUndefined(5)
diff --git a/doc/api/v8.markdown b/doc/api/v8.markdown
index 1cee348ba1ca9d..70abd6c6473f24 100644
--- a/doc/api/v8.markdown
+++ b/doc/api/v8.markdown
@@ -35,7 +35,7 @@ Usage:
 
 ```
 // Print GC events to stdout for one minute.
-var v8 = require('v8');
+const v8 = require('v8');
 v8.setFlagsFromString('--trace_gc');
 setTimeout(function() { v8.setFlagsFromString('--notrace_gc'); }, 60e3);
 ```
diff --git a/doc/api/vm.markdown b/doc/api/vm.markdown
index fd36c6b21f7ee0..07e99ac735677c 100644
--- a/doc/api/vm.markdown
+++ b/doc/api/vm.markdown
@@ -6,7 +6,7 @@
 
 You can access this module with:
 
-    var vm = require('vm');
+    const vm = require('vm');
 
 JavaScript code can be compiled and run immediately or compiled, saved, and run
 later.
@@ -48,8 +48,8 @@ and returns the result. Running code does not have access to local scope.
 Example: compile code that increments a global variable and sets one, then
 execute the code multiple times. These globals are contained in the sandbox.
 
-    var util = require('util');
-    var vm = require('vm');
+    const util = require('util');
+    const vm = require('vm');
 
     var sandbox = {
       animal: 'cat',
@@ -85,14 +85,14 @@ Example: compile code that sets a global variable, then execute the code
 multiple times in different contexts. These globals are set on and contained in
 the sandboxes.
 
-    var util = require('util');
-    var vm = require('vm');
+    const util = require('util');
+    const vm = require('vm');
 
-    var sandboxes = [{}, {}, {}];
+    const sandboxes = [{}, {}, {}];
 
-    var script = new vm.Script('globalVar = "set"');
+    const script = new vm.Script('globalVar = "set"');
 
-    sandboxes.forEach(function (sandbox) {
+    sandboxes.forEach((sandbox) => {
       script.runInNewContext(sandbox);
     });
 
@@ -114,11 +114,11 @@ current `global` object.
 Example of using `script.runInThisContext` to compile code once and run it
 multiple times:
 
-    var vm = require('vm');
+    const vm = require('vm');
 
     global.globalVar = 0;
 
-    var script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });
+    const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });
 
     for (var i = 0; i < 1000; ++i) {
       script.runInThisContext();
@@ -176,10 +176,10 @@ returns the result. Running code does not have access to local scope. The
 
 Example: compile and execute different scripts in a single existing context.
 
-    var util = require('util');
-    var vm = require('vm');
+    const util = require('util');
+    const vm = require('vm');
 
-    var sandbox = { globalVar: 1 };
+    const sandbox = { globalVar: 1 };
     vm.createContext(sandbox);
 
     for (var i = 0; i < 10; ++i) {
@@ -198,7 +198,7 @@ separate process.
 `vm.runInDebugContext` compiles and executes `code` inside the V8 debug context.
 The primary use case is to get access to the V8 debug object:
 
-    var Debug = vm.runInDebugContext('Debug');
+    const Debug = vm.runInDebugContext('Debug');
     Debug.scripts().forEach(function(script) { console.log(script.name); });
 
 Note that the debug context and object are intrinsically tied to V8's debugger
@@ -217,10 +217,10 @@ the sandbox as the global object and returns the result.
 Example: compile and execute code that increments a global variable and sets a
 new one. These globals are contained in the sandbox.
 
-    var util = require('util');
-    var vm = require('vm');
+    const util = require('util');
+    const vm = require('vm');
 
-    var sandbox = {
+    const sandbox = {
       animal: 'cat',
       count: 2
     };
@@ -242,14 +242,14 @@ code does not have access to local scope, but does have access to the current
 
 Example of using `vm.runInThisContext` and `eval` to run the same code:
 
-    var vm = require('vm');
+    const vm = require('vm');
     var localVar = 'initial value';
 
-    var vmResult = vm.runInThisContext('localVar = "vm";');
+    const vmResult = vm.runInThisContext('localVar = "vm";');
     console.log('vmResult: ', vmResult);
     console.log('localVar: ', localVar);
 
-    var evalResult = eval('localVar = "eval";');
+    const evalResult = eval('localVar = "eval";');
     console.log('evalResult: ', evalResult);
     console.log('localVar: ', localVar);
 
diff --git a/doc/api/zlib.markdown b/doc/api/zlib.markdown
index 5b1cf407820d53..5f238be5bff8d8 100644
--- a/doc/api/zlib.markdown
+++ b/doc/api/zlib.markdown
@@ -4,7 +4,7 @@
 
 You can access this module with:
 
-    var zlib = require('zlib');
+    const zlib = require('zlib');
 
 This provides bindings to Gzip/Gunzip, Deflate/Inflate, and
 DeflateRaw/InflateRaw classes.  Each class takes the same options, and
@@ -15,24 +15,24 @@ is a readable/writable Stream.
 Compressing or decompressing a file can be done by piping an
 fs.ReadStream into a zlib stream, then into an fs.WriteStream.
 
-    var gzip = zlib.createGzip();
-    var fs = require('fs');
-    var inp = fs.createReadStream('input.txt');
-    var out = fs.createWriteStream('input.txt.gz');
+    const gzip = zlib.createGzip();
+    const fs = require('fs');
+    const inp = fs.createReadStream('input.txt');
+    const out = fs.createWriteStream('input.txt.gz');
 
     inp.pipe(gzip).pipe(out);
 
 Compressing or decompressing data in one step can be done by using
 the convenience methods.
 
-    var input = '.................................';
+    const input = '.................................';
     zlib.deflate(input, function(err, buffer) {
       if (!err) {
         console.log(buffer.toString('base64'));
       }
     });
 
-    var buffer = new Buffer('eJzT0yMAAGTvBe8=', 'base64');
+    const buffer = new Buffer('eJzT0yMAAGTvBe8=', 'base64');
     zlib.unzip(buffer, function(err, buffer) {
       if (!err) {
         console.log(buffer.toString());
@@ -48,14 +48,14 @@ ought to be cached.  See [Memory Usage Tuning][] below for more information
 on the speed/memory/compression tradeoffs involved in zlib usage.
 
     // client request example
-    var zlib = require('zlib');
-    var http = require('http');
-    var fs = require('fs');
-    var request = http.get({ host: 'izs.me',
+    const zlib = require('zlib');
+    const http = require('http');
+    const fs = require('fs');
+    const request = http.get({ host: 'izs.me',
                              path: '/',
                              port: 80,
                              headers: { 'accept-encoding': 'gzip,deflate' } });
-    request.on('response', function(response) {
+    request.on('response', (response) => {
       var output = fs.createWriteStream('izs.me_index.html');
 
       switch (response.headers['content-encoding']) {
@@ -75,10 +75,10 @@ on the speed/memory/compression tradeoffs involved in zlib usage.
     // server example
     // Running a gzip operation on every request is quite expensive.
     // It would be much more efficient to cache the compressed buffer.
-    var zlib = require('zlib');
-    var http = require('http');
-    var fs = require('fs');
-    http.createServer(function(request, response) {
+    const zlib = require('zlib');
+    const http = require('http');
+    const fs = require('fs');
+    http.createServer((request, response) => {
       var raw = fs.createReadStream('index.html');
       var acceptEncoding = request.headers['accept-encoding'];
       if (!acceptEncoding) {

From 645577f55f0f1f014f9650bd379e359593a65e9c Mon Sep 17 00:00:00 2001
From: Bo Borgerson <gigabo@gmail.com>
Date: Wed, 16 Dec 2015 18:31:38 -0800
Subject: [PATCH 05/23] http: Remove an unnecessary assignment

This just removes an assignment to `ret` of a value that's not used before
it's overwritten.  Immediately following the assigment is an `if/else` in
which both branches assign to `ret` without using it.

PR-URL: https://github.com/nodejs/node/pull/4323
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Brian White <mscdex@mscdex.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
---
 lib/_http_outgoing.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js
index e3a258b1cddd12..72c5374f7b1262 100644
--- a/lib/_http_outgoing.js
+++ b/lib/_http_outgoing.js
@@ -572,7 +572,7 @@ OutgoingMessage.prototype.end = function(data, encoding, callback) {
   var ret;
   if (data) {
     // Normal body write.
-    ret = this.write(data, encoding);
+    this.write(data, encoding);
   }
 
   if (this._hasBody && this.chunkedEncoding) {

From 1a07eabe7becbd957bf8a3c543b6accee9db0be9 Mon Sep 17 00:00:00 2001
From: Ben Noordhuis <info@bnoordhuis.nl>
Date: Thu, 17 Dec 2015 12:13:11 +0100
Subject: [PATCH 06/23] debugger: guard against call from non-node context

Fix a segmentation fault when the debug message handler was called from
a context without an associated `node::Environment`.

Fixes: https://github.com/nodejs/node/issues/4261
Fixes: https://github.com/nodejs/node/issues/4322
PR-URL: https://github.com/nodejs/node/pull/4328
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
---
 src/debug-agent.cc                     |  2 ++
 test/parallel/test-debug-no-context.js | 24 ++++++++++++++++++++++++
 2 files changed, 26 insertions(+)
 create mode 100644 test/parallel/test-debug-no-context.js

diff --git a/src/debug-agent.cc b/src/debug-agent.cc
index 3409fb2603ae9b..06ede7fdef4aa9 100644
--- a/src/debug-agent.cc
+++ b/src/debug-agent.cc
@@ -321,6 +321,8 @@ void Agent::EnqueueMessage(AgentMessage* message) {
 void Agent::MessageHandler(const v8::Debug::Message& message) {
   Isolate* isolate = message.GetIsolate();
   Environment* env = Environment::GetCurrent(isolate);
+  if (env == nullptr)
+    return;  // Called from a non-node context.
   Agent* a = env->debugger_agent();
   CHECK_NE(a, nullptr);
   CHECK_EQ(isolate, a->parent_env()->isolate());
diff --git a/test/parallel/test-debug-no-context.js b/test/parallel/test-debug-no-context.js
new file mode 100644
index 00000000000000..a143e67ac66cd5
--- /dev/null
+++ b/test/parallel/test-debug-no-context.js
@@ -0,0 +1,24 @@
+'use strict';
+
+const common = require('../common');
+const assert = require('assert');
+const spawn = require('child_process').spawn;
+
+const args = [`--debug`, `--debug-port=${common.PORT}`, `--interactive`];
+const proc = spawn(process.execPath, args, { stdio: 'pipe' });
+proc.stdin.write(`
+    util.inspect(Promise.resolve(42));
+    util.inspect(Promise.resolve(1337));
+    .exit
+`);
+proc.on('exit', common.mustCall((exitCode, signalCode) => {
+  assert.strictEqual(exitCode, 0);
+  assert.strictEqual(signalCode, null);
+}));
+let stdout = '';
+proc.stdout.setEncoding('utf8');
+proc.stdout.on('data', data => stdout += data);
+process.on('exit', () => {
+  assert(stdout.includes('Promise { 42 }'));
+  assert(stdout.includes('Promise { 1337 }'));
+});

From d187c6e80074a5e226ac38f7758b49cfcbcbf23b Mon Sep 17 00:00:00 2001
From: Brian White <mscdex@mscdex.net>
Date: Thu, 17 Dec 2015 01:16:46 -0500
Subject: [PATCH 07/23] test: try other ipv6 localhost alternatives

PR-URL: https://github.com/nodejs/node/pull/4325
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
---
 test/common.js                                | 13 +++
 .../parallel/test-net-connect-options-ipv6.js | 96 +++++++++++--------
 2 files changed, 68 insertions(+), 41 deletions(-)

diff --git a/test/common.js b/test/common.js
index 3bb5d51f0127a7..bd9d4956c901ce 100644
--- a/test/common.js
+++ b/test/common.js
@@ -81,6 +81,19 @@ var opensslCli = null;
 var inFreeBSDJail = null;
 var localhostIPv4 = null;
 
+exports.localIPv6Hosts = [
+  // Debian/Ubuntu
+  'ip6-localhost',
+  'ip6-loopback',
+
+  // SUSE
+  'ipv6-localhost',
+  'ipv6-loopback',
+
+  // Typically universal
+  'localhost',
+];
+
 Object.defineProperty(exports, 'inFreeBSDJail', {
   get: function() {
     if (inFreeBSDJail !== null) return inFreeBSDJail;
diff --git a/test/parallel/test-net-connect-options-ipv6.js b/test/parallel/test-net-connect-options-ipv6.js
index f0f7bc65b3c7eb..623b2eff1ddded 100644
--- a/test/parallel/test-net-connect-options-ipv6.js
+++ b/test/parallel/test-net-connect-options-ipv6.js
@@ -1,8 +1,8 @@
 'use strict';
-var common = require('../common');
-var assert = require('assert');
-var net = require('net');
-var dns = require('dns');
+const common = require('../common');
+const assert = require('assert');
+const net = require('net');
+const dns = require('dns');
 
 if (!common.hasIPv6) {
   console.log('1..0 # Skipped: no IPv6 support');
@@ -12,46 +12,60 @@ if (!common.hasIPv6) {
 var serverGotEnd = false;
 var clientGotEnd = false;
 
-dns.lookup('localhost', 6, function(err) {
-  if (err) {
-    console.error('Looks like IPv6 is not really supported');
-    console.error(err);
-    return;
-  }
+const hosts = common.localIPv6Hosts;
+var hostIdx = 0;
+var host = hosts[hostIdx];
+var localhostTries = 10;
 
-  var server = net.createServer({allowHalfOpen: true}, function(socket) {
-    socket.resume();
-    socket.on('end', function() {
-      serverGotEnd = true;
-    });
-    socket.end();
+const server = net.createServer({allowHalfOpen: true}, function(socket) {
+  socket.resume();
+  socket.on('end', function() {
+    serverGotEnd = true;
   });
+  socket.end();
+});
 
-  server.listen(common.PORT, '::1', function() {
-    var client = net.connect({
-      host: 'localhost',
-      port: common.PORT,
-      family: 6,
-      allowHalfOpen: true
-    }, function() {
-      console.error('client connect cb');
-      client.resume();
-      client.on('end', function() {
-        clientGotEnd = true;
-        setTimeout(function() {
-          assert(client.writable);
-          client.end();
-        }, 10);
-      });
-      client.on('close', function() {
-        server.close();
-      });
+server.listen(common.PORT, '::1', tryConnect);
+
+function tryConnect() {
+  const client = net.connect({
+    host: host,
+    port: common.PORT,
+    family: 6,
+    allowHalfOpen: true
+  }, function() {
+    console.error('client connect cb');
+    client.resume();
+    client.on('end', function() {
+      clientGotEnd = true;
+      setTimeout(function() {
+        assert(client.writable);
+        client.end();
+      }, 10);
+    });
+    client.on('close', function() {
+      server.close();
     });
+  }).on('error', function(err) {
+    if (err.syscall === 'getaddrinfo' && err.code === 'ENOTFOUND') {
+      if (host !== 'localhost' || --localhostTries === 0)
+        host = hosts[++hostIdx];
+      if (host)
+        tryConnect();
+      else {
+        console.log('1..0 # Skipped: no IPv6 localhost support');
+        process.removeListener('exit', onExit);
+        server.close();
+      }
+      return;
+    }
+    throw err;
   });
+}
 
-  process.on('exit', function() {
-    console.error('exit', serverGotEnd, clientGotEnd);
-    assert(serverGotEnd);
-    assert(clientGotEnd);
-  });
-});
+process.on('exit', onExit);
+function onExit() {
+  console.error('exit', serverGotEnd, clientGotEnd);
+  assert(serverGotEnd);
+  assert(clientGotEnd);
+}

From 89c32bc491bb09acd6f24b7fa3445185def5e3fa Mon Sep 17 00:00:00 2001
From: Trevor Norris <trev.norris@gmail.com>
Date: Tue, 10 Nov 2015 02:58:51 -0700
Subject: [PATCH 08/23] node: fix erroneously named function call

The initial implementation of setPropByIndex() set the value of an Array
by index during development. Though the final form of the function
simply pushes passed values to an array as passed by arguments. Thus the
functions have been renamed to pushValueToArray() and
push_values_to_array_function() respectively.

Also add define for maximum number of arguments should be used before
hitting the limit of performance increase.

Fixes: 494227b "node: improve GetActiveRequests performance"
PR-URL: https://github.com/nodejs/node/pull/3780
Reviewed-By: Fedor Indutny <fedor@indutny.com>
---
 src/env.h   | 12 +++++++++---
 src/node.cc |  4 ++--
 src/node.js |  4 ++--
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/src/env.h b/src/env.h
index 0c616ddef21400..6151c57069ad7b 100644
--- a/src/env.h
+++ b/src/env.h
@@ -38,6 +38,12 @@ namespace node {
 #define NODE_ISOLATE_SLOT 3
 #endif
 
+// The number of items passed to push_values_to_array_function has diminishing
+// returns around 8. This should be used at all call sites using said function.
+#ifndef NODE_PUSH_VAL_TO_ARRAY_MAX
+#define NODE_PUSH_VAL_TO_ARRAY_MAX 8
+#endif
+
 // Strings are per-isolate primitives but Environment proxies them
 // for the sake of convenience.  Strings should be ASCII-only.
 #define PER_ISOLATE_STRING_PROPERTIES(V)                                      \
@@ -231,12 +237,11 @@ namespace node {
   V(zero_return_string, "ZERO_RETURN")                                        \
 
 #define ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)                           \
-  V(add_properties_by_index_function, v8::Function)                           \
   V(as_external, v8::External)                                                \
+  V(async_hooks_destroy_function, v8::Function)                               \
   V(async_hooks_init_function, v8::Function)                                  \
-  V(async_hooks_pre_function, v8::Function)                                   \
   V(async_hooks_post_function, v8::Function)                                  \
-  V(async_hooks_destroy_function, v8::Function)                               \
+  V(async_hooks_pre_function, v8::Function)                                   \
   V(binding_cache_object, v8::Object)                                         \
   V(buffer_constructor_function, v8::Function)                                \
   V(buffer_prototype_object, v8::Object)                                      \
@@ -250,6 +255,7 @@ namespace node {
   V(pipe_constructor_template, v8::FunctionTemplate)                          \
   V(process_object, v8::Object)                                               \
   V(promise_reject_function, v8::Function)                                    \
+  V(push_values_to_array_function, v8::Function)                              \
   V(script_context_constructor_template, v8::FunctionTemplate)                \
   V(script_data_constructor_function, v8::Function)                           \
   V(secure_context_constructor_template, v8::FunctionTemplate)                \
diff --git a/src/node.cc b/src/node.cc
index 49cfc8a06053d2..4c08bae04bdeef 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -1063,7 +1063,7 @@ void SetupProcessObject(const FunctionCallbackInfo<Value>& args) {
 
   CHECK(args[0]->IsFunction());
 
-  env->set_add_properties_by_index_function(args[0].As<Function>());
+  env->set_push_values_to_array_function(args[0].As<Function>());
   env->process_object()->Delete(
       FIXED_ONE_BYTE_STRING(env->isolate(), "_setupProcessObject"));
 }
@@ -1607,7 +1607,7 @@ static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
 
   Local<Array> ary = Array::New(args.GetIsolate());
   Local<Context> ctx = env->context();
-  Local<Function> fn = env->add_properties_by_index_function();
+  Local<Function> fn = env->push_values_to_array_function();
   static const size_t argc = 8;
   Local<Value> argv[argc];
   size_t i = 0;
diff --git a/src/node.js b/src/node.js
index 34aae9395442a0..8d77adc27c4102 100644
--- a/src/node.js
+++ b/src/node.js
@@ -181,9 +181,9 @@
   }
 
   startup.setupProcessObject = function() {
-    process._setupProcessObject(setPropByIndex);
+    process._setupProcessObject(pushValueToArray);
 
-    function setPropByIndex() {
+    function pushValueToArray() {
       for (var i = 0; i < arguments.length; i++)
         this.push(arguments[i]);
     }

From 369f795132b4e817143a09677cc231da3db379d6 Mon Sep 17 00:00:00 2001
From: Trevor Norris <trev.norris@gmail.com>
Date: Tue, 10 Nov 2015 03:04:26 -0700
Subject: [PATCH 09/23] http_parser: use pushValueToArray for headers

For performance add headers to the headers Array by pushing them on from
JS. Benchmark added to demonstrate this case.

PR-URL: https://github.com/nodejs/node/pull/3780
Reviewed-By: Fedor Indutny <fedor@indutny.com>
---
 benchmark/http/bench-parser.js | 55 ++++++++++++++++++++++++++++++++++
 src/node_http_parser.cc        | 23 ++++++++++----
 2 files changed, 72 insertions(+), 6 deletions(-)
 create mode 100644 benchmark/http/bench-parser.js

diff --git a/benchmark/http/bench-parser.js b/benchmark/http/bench-parser.js
new file mode 100644
index 00000000000000..989d9a994fa04e
--- /dev/null
+++ b/benchmark/http/bench-parser.js
@@ -0,0 +1,55 @@
+'use strict';
+
+const common = require('../common');
+const HTTPParser = process.binding('http_parser').HTTPParser;
+const REQUEST = HTTPParser.REQUEST;
+const kOnHeaders = HTTPParser.kOnHeaders | 0;
+const kOnHeadersComplete = HTTPParser.kOnHeadersComplete | 0;
+const kOnBody = HTTPParser.kOnBody | 0;
+const kOnMessageComplete = HTTPParser.kOnMessageComplete | 0;
+const CRLF = '\r\n';
+
+const bench = common.createBenchmark(main, {
+  fields: [4, 8, 16, 32],
+  n: [1e5],
+});
+
+
+function main(conf) {
+  const fields = conf.fields >>> 0;
+  const n = conf.n >>> 0;
+  var header = `GET /hello HTTP/1.1${CRLF}Content-Type: text/plain${CRLF}`;
+
+  for (var i = 0; i < fields; i++) {
+    header += `X-Filler${i}: ${Math.random().toString(36).substr(2)}${CRLF}`;
+  }
+  header += CRLF;
+
+  processHeader(new Buffer(header), n);
+}
+
+
+function processHeader(header, n) {
+  const parser = newParser(REQUEST);
+
+  bench.start();
+  for (var i = 0; i < n; i++) {
+    parser.execute(header, 0, header.length);
+    parser.reinitialize(REQUEST);
+  }
+  bench.end(n);
+}
+
+
+function newParser(type) {
+  const parser = new HTTPParser(type);
+
+  parser.headers = [];
+
+  parser[kOnHeaders] = function() { };
+  parser[kOnHeadersComplete] = function() { };
+  parser[kOnBody] = function() { };
+  parser[kOnMessageComplete] = function() { };
+
+  return parser;
+}
diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc
index ff3dfb26e529af..28322f95c40939 100644
--- a/src/node_http_parser.cc
+++ b/src/node_http_parser.cc
@@ -632,12 +632,23 @@ class Parser : public BaseObject {
   Local<Array> CreateHeaders() {
     // num_values_ is either -1 or the entry # of the last header
     // so num_values_ == 0 means there's a single header
-    Local<Array> headers = Array::New(env()->isolate(), 2 * num_values_);
-
-    for (int i = 0; i < num_values_; ++i) {
-      headers->Set(2 * i, fields_[i].ToString(env()));
-      headers->Set(2 * i + 1, values_[i].ToString(env()));
-    }
+    Local<Array> headers = Array::New(env()->isolate());
+    Local<Function> fn = env()->push_values_to_array_function();
+    Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX * 2];
+    int i = 0;
+
+    do {
+      size_t j = 0;
+      while (i < num_values_ && j < ARRAY_SIZE(argv) / 2) {
+        argv[j * 2] = fields_[i].ToString(env());
+        argv[j * 2 + 1] = values_[i].ToString(env());
+        i++;
+        j++;
+      }
+      if (j > 0) {
+        fn->Call(env()->context(), headers, j * 2, argv).ToLocalChecked();
+      }
+    } while (i < num_values_);
 
     return headers;
   }

From 3f19d4a320672bcaf5e8dce0b02d65e421734bb5 Mon Sep 17 00:00:00 2001
From: Trevor Norris <trev.norris@gmail.com>
Date: Tue, 10 Nov 2015 16:36:50 -0700
Subject: [PATCH 10/23] fs: use pushValueToArray for readdir(Sync)

Improve performance by pushing directory entries to returned array in
batches of 8 using pushValueToArray() in JS. Add benchmarks to
demonstrate this improvement.

PR-URL: https://github.com/nodejs/node/pull/3780
Reviewed-By: Fedor Indutny <fedor@indutny.com>
---
 benchmark/fs/bench-readdir.js     | 22 ++++++++++++++++++
 benchmark/fs/bench-readdirSync.js | 19 ++++++++++++++++
 src/node_file.cc                  | 37 ++++++++++++++++++++++++++-----
 3 files changed, 72 insertions(+), 6 deletions(-)
 create mode 100644 benchmark/fs/bench-readdir.js
 create mode 100644 benchmark/fs/bench-readdirSync.js

diff --git a/benchmark/fs/bench-readdir.js b/benchmark/fs/bench-readdir.js
new file mode 100644
index 00000000000000..2f0eab6a821f42
--- /dev/null
+++ b/benchmark/fs/bench-readdir.js
@@ -0,0 +1,22 @@
+'use strict';
+
+const common = require('../common');
+const fs = require('fs');
+
+const bench = common.createBenchmark(main, {
+  n: [1e4],
+});
+
+
+function main(conf) {
+  const n = conf.n >>> 0;
+
+  bench.start();
+  (function r(cntr) {
+    if (--cntr <= 0)
+      return bench.end(n);
+    fs.readdir(__dirname + '/../../lib/', function() {
+      r(cntr);
+    });
+  }(n));
+}
diff --git a/benchmark/fs/bench-readdirSync.js b/benchmark/fs/bench-readdirSync.js
new file mode 100644
index 00000000000000..9f89649138cd20
--- /dev/null
+++ b/benchmark/fs/bench-readdirSync.js
@@ -0,0 +1,19 @@
+'use strict';
+
+const common = require('../common');
+const fs = require('fs');
+
+const bench = common.createBenchmark(main, {
+  n: [1e4],
+});
+
+
+function main(conf) {
+  const n = conf.n >>> 0;
+
+  bench.start();
+  for (var i = 0; i < n; i++) {
+    fs.readdirSync(__dirname + '/../../lib/');
+  }
+  bench.end(n);
+}
diff --git a/src/node_file.cc b/src/node_file.cc
index b6ef7d5b78f70e..5c1b39864c5508 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -214,6 +214,9 @@ static void After(uv_fs_t *req) {
         {
           int r;
           Local<Array> names = Array::New(env->isolate(), 0);
+          Local<Function> fn = env->push_values_to_array_function();
+          Local<Value> name_argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
+          size_t name_idx = 0;
 
           for (int i = 0; ; i++) {
             uv_dirent_t ent;
@@ -229,9 +232,19 @@ static void After(uv_fs_t *req) {
               break;
             }
 
-            Local<String> name = String::NewFromUtf8(env->isolate(),
-                                                     ent.name);
-            names->Set(i, name);
+            name_argv[name_idx++] =
+                String::NewFromUtf8(env->isolate(), ent.name);
+
+            if (name_idx >= ARRAY_SIZE(name_argv)) {
+              fn->Call(env->context(), names, name_idx, name_argv)
+                  .ToLocalChecked();
+              name_idx = 0;
+            }
+          }
+
+          if (name_idx > 0) {
+            fn->Call(env->context(), names, name_idx, name_argv)
+                .ToLocalChecked();
           }
 
           argv[1] = names;
@@ -811,6 +824,9 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
     CHECK_GE(SYNC_REQ.result, 0);
     int r;
     Local<Array> names = Array::New(env->isolate(), 0);
+    Local<Function> fn = env->push_values_to_array_function();
+    Local<Value> name_v[NODE_PUSH_VAL_TO_ARRAY_MAX];
+    size_t name_idx = 0;
 
     for (int i = 0; ; i++) {
       uv_dirent_t ent;
@@ -821,9 +837,18 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
       if (r != 0)
         return env->ThrowUVException(r, "readdir", "", *path);
 
-      Local<String> name = String::NewFromUtf8(env->isolate(),
-                                               ent.name);
-      names->Set(i, name);
+
+      name_v[name_idx++] = String::NewFromUtf8(env->isolate(), ent.name);
+
+      if (name_idx >= ARRAY_SIZE(name_v)) {
+        fn->Call(env->context(), names, name_idx, name_v)
+            .ToLocalChecked();
+        name_idx = 0;
+      }
+    }
+
+    if (name_idx > 0) {
+      fn->Call(env->context(), names, name_idx, name_v).ToLocalChecked();
     }
 
     args.GetReturnValue().Set(names);

From 4f078661f348eb09bbf0446616533418c03469e9 Mon Sep 17 00:00:00 2001
From: Trevor Norris <trev.norris@gmail.com>
Date: Tue, 10 Nov 2015 17:04:56 -0700
Subject: [PATCH 11/23] node: improve GetActiveHandles performance

Improve performance of process._getActiveHandles by sending handles in
batches to JS to be set on the passed Array. Add test to check proper
active handles are returned.

Alter implementation of GetActiveRequests to match GetActiveHandles'
implementation.

PR-URL: https://github.com/nodejs/node/pull/3780
Reviewed-By: Fedor Indutny <fedor@indutny.com>
---
 src/node.cc                                   | 40 +++++++++--------
 .../parallel/test-process-getactivehandles.js | 44 +++++++++++++++++++
 2 files changed, 66 insertions(+), 18 deletions(-)
 create mode 100644 test/parallel/test-process-getactivehandles.js

diff --git a/src/node.cc b/src/node.cc
index 4c08bae04bdeef..be80ab3124d716 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -1608,27 +1608,21 @@ static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
   Local<Array> ary = Array::New(args.GetIsolate());
   Local<Context> ctx = env->context();
   Local<Function> fn = env->push_values_to_array_function();
-  static const size_t argc = 8;
-  Local<Value> argv[argc];
-  size_t i = 0;
+  Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
+  size_t idx = 0;
 
   for (auto w : *env->req_wrap_queue()) {
-    if (w->persistent().IsEmpty() == false) {
-      argv[i++ % argc] = w->object();
-      if ((i % argc) == 0) {
-        HandleScope scope(env->isolate());
-        fn->Call(ctx, ary, argc, argv).ToLocalChecked();
-        for (auto&& arg : argv) {
-          arg = Local<Value>();
-        }
-      }
+    if (w->persistent().IsEmpty())
+      continue;
+    argv[idx] = w->object();
+    if (++idx >= ARRAY_SIZE(argv)) {
+      fn->Call(ctx, ary, idx, argv).ToLocalChecked();
+      idx = 0;
     }
   }
 
-  const size_t remainder = i % argc;
-  if (remainder > 0) {
-    HandleScope scope(env->isolate());
-    fn->Call(ctx, ary, remainder, argv).ToLocalChecked();
+  if (idx > 0) {
+    fn->Call(ctx, ary, idx, argv).ToLocalChecked();
   }
 
   args.GetReturnValue().Set(ary);
@@ -1641,7 +1635,10 @@ void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
   Environment* env = Environment::GetCurrent(args);
 
   Local<Array> ary = Array::New(env->isolate());
-  int i = 0;
+  Local<Context> ctx = env->context();
+  Local<Function> fn = env->push_values_to_array_function();
+  Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
+  size_t idx = 0;
 
   Local<String> owner_sym = env->owner_string();
 
@@ -1652,7 +1649,14 @@ void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
     Local<Value> owner = object->Get(owner_sym);
     if (owner->IsUndefined())
       owner = object;
-    ary->Set(i++, owner);
+    argv[idx] = owner;
+    if (++idx >= ARRAY_SIZE(argv)) {
+      fn->Call(ctx, ary, idx, argv).ToLocalChecked();
+      idx = 0;
+    }
+  }
+  if (idx > 0) {
+    fn->Call(ctx, ary, idx, argv).ToLocalChecked();
   }
 
   args.GetReturnValue().Set(ary);
diff --git a/test/parallel/test-process-getactivehandles.js b/test/parallel/test-process-getactivehandles.js
new file mode 100644
index 00000000000000..96464cf3b22fcd
--- /dev/null
+++ b/test/parallel/test-process-getactivehandles.js
@@ -0,0 +1,44 @@
+'use strict';
+
+const common = require('../common');
+const assert = require('assert');
+const net = require('net');
+const NUM = 8;
+const connections = [];
+const clients = [];
+var clients_counter = 0;
+
+const server = net.createServer(function listener(c) {
+  connections.push(c);
+}).listen(common.PORT, function makeConnections() {
+  for (var i = 0; i < NUM; i++) {
+    net.connect(common.PORT, function connected() {
+      clientConnected(this);
+    });
+  }
+});
+
+
+function clientConnected(client) {
+  clients.push(client);
+  if (++clients_counter >= NUM)
+    checkAll();
+}
+
+
+function checkAll() {
+  const handles = process._getActiveHandles();
+
+  clients.forEach(function(item) {
+    assert.ok(handles.indexOf(item) > -1);
+    item.destroy();
+  });
+
+  connections.forEach(function(item) {
+    assert.ok(handles.indexOf(item) > -1);
+    item.end();
+  });
+
+  assert.ok(handles.indexOf(server) > -1);
+  server.close();
+}

From b73bb71ab4529714d9acc3e5c54511a420e31272 Mon Sep 17 00:00:00 2001
From: Trevor Norris <trev.norris@gmail.com>
Date: Wed, 11 Nov 2015 00:15:15 -0700
Subject: [PATCH 12/23] node: improve performance of hrtime()

process.hrtime() was performing too many operations in C++ that could be
done faster in JS. Move those operations over by creating a length 4
Uint32Array and perform bitwise operations on the seconds so that it was
unnecessary for the native API to do any object creation or set any
fields.

This has improved performance from ~350 ns/op to ~65 ns/op. Light
benchmark included to demonstrate the performance change.

PR-URL: https://github.com/nodejs/node/pull/3780
Reviewed-By: Fedor Indutny <fedor@indutny.com>
---
 benchmark/misc/bench-hrtime.js | 18 ++++++++++++++++++
 src/node.cc                    | 25 +++++++++++++------------
 src/node.js                    | 15 +++++++++++++++
 3 files changed, 46 insertions(+), 12 deletions(-)
 create mode 100644 benchmark/misc/bench-hrtime.js

diff --git a/benchmark/misc/bench-hrtime.js b/benchmark/misc/bench-hrtime.js
new file mode 100644
index 00000000000000..661dff43b0103c
--- /dev/null
+++ b/benchmark/misc/bench-hrtime.js
@@ -0,0 +1,18 @@
+'use strict';
+
+const common = require('../common');
+
+const bench = common.createBenchmark(main, {
+  n: [1e6]
+});
+
+
+function main(conf) {
+  const n = conf.n >>> 0;
+
+  bench.start();
+  for (var i = 0; i < n; i++) {
+    process.hrtime();
+  }
+  bench.end(n);
+}
diff --git a/src/node.cc b/src/node.cc
index be80ab3124d716..e03d541f3ceb32 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -2132,22 +2132,23 @@ void Hrtime(const FunctionCallbackInfo<Value>& args) {
 
   uint64_t t = uv_hrtime();
 
-  if (args.Length() > 0) {
-    // return a time diff tuple
-    if (!args[0]->IsArray()) {
+  if (!args[1]->IsUndefined()) {
+    if (!args[1]->IsArray()) {
       return env->ThrowTypeError(
-          "process.hrtime() only accepts an Array tuple.");
+          "process.hrtime() only accepts an Array tuple");
     }
-    Local<Array> inArray = Local<Array>::Cast(args[0]);
-    uint64_t seconds = inArray->Get(0)->Uint32Value();
-    uint64_t nanos = inArray->Get(1)->Uint32Value();
-    t -= (seconds * NANOS_PER_SEC) + nanos;
+    args.GetReturnValue().Set(true);
   }
 
-  Local<Array> tuple = Array::New(env->isolate(), 2);
-  tuple->Set(0, Integer::NewFromUnsigned(env->isolate(), t / NANOS_PER_SEC));
-  tuple->Set(1, Integer::NewFromUnsigned(env->isolate(), t % NANOS_PER_SEC));
-  args.GetReturnValue().Set(tuple);
+  Local<ArrayBuffer> ab = args[0].As<Uint32Array>()->Buffer();
+  uint32_t* fields = static_cast<uint32_t*>(ab->GetContents().Data());
+
+  // These three indices will contain the values for the hrtime tuple. The
+  // seconds value is broken into the upper/lower 32 bits and stored in two
+  // uint32 fields to be converted back in JS.
+  fields[0] = (t / NANOS_PER_SEC) >> 32;
+  fields[1] = (t / NANOS_PER_SEC) & 0xffffffff;
+  fields[2] = t % NANOS_PER_SEC;
 }
 
 extern "C" void node_module_register(void* m) {
diff --git a/src/node.js b/src/node.js
index 8d77adc27c4102..f91b20ef60d28b 100644
--- a/src/node.js
+++ b/src/node.js
@@ -181,12 +181,27 @@
   }
 
   startup.setupProcessObject = function() {
+    const _hrtime = process.hrtime;
+    const hrValues = new Uint32Array(3);
+
     process._setupProcessObject(pushValueToArray);
 
     function pushValueToArray() {
       for (var i = 0; i < arguments.length; i++)
         this.push(arguments[i]);
     }
+
+    process.hrtime = function hrtime(ar) {
+      const ret = [0, 0];
+      if (_hrtime(hrValues, ar)) {
+        ret[0] = (hrValues[0] * 0x100000000 + hrValues[1]) - ar[0];
+        ret[1] = hrValues[2] - ar[1];
+      } else {
+        ret[0] = hrValues[0] * 0x100000000 + hrValues[1];
+        ret[1] = hrValues[2];
+      }
+      return ret;
+    };
   };
 
   startup.globalVariables = function() {

From e80865835f550fc6b7e9ffc4820514c57884cb8c Mon Sep 17 00:00:00 2001
From: Trevor Norris <trev.norris@gmail.com>
Date: Wed, 11 Nov 2015 12:28:41 -0700
Subject: [PATCH 13/23] node: improve accessor perf of process.env

Set process.env array entries in JS.

PR-URL: https://github.com/nodejs/node/pull/3780
Reviewed-By: Fedor Indutny <fedor@indutny.com>
---
 benchmark/misc/bench-env.js | 18 ++++++++++++++++
 src/node.cc                 | 43 ++++++++++++++++++++++++++-----------
 2 files changed, 48 insertions(+), 13 deletions(-)
 create mode 100644 benchmark/misc/bench-env.js

diff --git a/benchmark/misc/bench-env.js b/benchmark/misc/bench-env.js
new file mode 100644
index 00000000000000..66f966f587bb7f
--- /dev/null
+++ b/benchmark/misc/bench-env.js
@@ -0,0 +1,18 @@
+'use strict';
+
+const common = require('../common');
+
+const bench = common.createBenchmark(main, {
+  n: [1e5],
+});
+
+
+function main(conf) {
+  const n = conf.n >>> 0;
+  bench.start();
+  for (var i = 0; i < n; i++) {
+    // Access every item in object to process values.
+    Object.keys(process.env);
+  }
+  bench.end(n);
+}
diff --git a/src/node.cc b/src/node.cc
index e03d541f3ceb32..f9797e664ef937 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -2560,23 +2560,35 @@ static void EnvDeleter(Local<String> property,
 
 
 static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
-  Isolate* isolate = info.GetIsolate();
+  Environment* env = Environment::GetCurrent(info);
+  Isolate* isolate = env->isolate();
+  Local<Context> ctx = env->context();
+  Local<Function> fn = env->push_values_to_array_function();
+  Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
+  size_t idx = 0;
+
 #ifdef __POSIX__
   int size = 0;
   while (environ[size])
     size++;
 
-  Local<Array> envarr = Array::New(isolate, size);
+  Local<Array> envarr = Array::New(isolate);
 
   for (int i = 0; i < size; ++i) {
     const char* var = environ[i];
     const char* s = strchr(var, '=');
     const int length = s ? s - var : strlen(var);
-    Local<String> name = String::NewFromUtf8(isolate,
-                                             var,
-                                             String::kNormalString,
-                                             length);
-    envarr->Set(i, name);
+    argv[idx] = String::NewFromUtf8(isolate,
+                                    var,
+                                    String::kNormalString,
+                                    length);
+    if (++idx >= ARRAY_SIZE(argv)) {
+      fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
+      idx = 0;
+    }
+  }
+  if (idx > 0) {
+    fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
   }
 #else  // _WIN32
   WCHAR* environment = GetEnvironmentStringsW();
@@ -2584,7 +2596,6 @@ static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
     return;  // This should not happen.
   Local<Array> envarr = Array::New(isolate);
   WCHAR* p = environment;
-  int i = 0;
   while (*p) {
     WCHAR *s;
     if (*p == L'=') {
@@ -2599,13 +2610,19 @@ static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
     }
     const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p);
     const size_t two_byte_buffer_len = s - p;
-    Local<String> value = String::NewFromTwoByte(isolate,
-                                                 two_byte_buffer,
-                                                 String::kNormalString,
-                                                 two_byte_buffer_len);
-    envarr->Set(i++, value);
+    argv[idx] = String::NewFromTwoByte(isolate,
+                                       two_byte_buffer,
+                                       String::kNormalString,
+                                       two_byte_buffer_len);
+    if (++idx >= ARRAY_SIZE(argv)) {
+      fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
+      idx = 0;
+    }
     p = s + wcslen(s) + 1;
   }
+  if (idx > 0) {
+    fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
+  }
   FreeEnvironmentStringsW(environment);
 #endif
 

From 6406dbb4b203a5171feb888d1c92f6cc3371f9ee Mon Sep 17 00:00:00 2001
From: Fedor Indutny <fedor@indutny.com>
Date: Sat, 5 Dec 2015 16:53:30 -0500
Subject: [PATCH 14/23] crypto: load PFX chain the same way as regular one

Load the certificate chain from the PFX file the same as we do it for a
regular certificate chain.

Fix: #4127
PR-URL: https://github.com/nodejs/node/pull/4165
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
---
 src/node_crypto.cc                      | 170 +++++++++++++++++-------
 test/fixtures/keys/Makefile             |   8 ++
 test/fixtures/keys/agent1-pfx.pem       | Bin 0 -> 2437 bytes
 test/parallel/test-tls-ocsp-callback.js |  33 ++++-
 4 files changed, 156 insertions(+), 55 deletions(-)
 create mode 100644 test/fixtures/keys/agent1-pfx.pem

diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 63d767a1f4cd7c..d120fed7cc70bb 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -517,46 +517,35 @@ int SSL_CTX_get_issuer(SSL_CTX* ctx, X509* cert, X509** issuer) {
 }
 
 
-// Read a file that contains our certificate in "PEM" format,
-// possibly followed by a sequence of CA certificates that should be
-// sent to the peer in the Certificate message.
-//
-// Taken from OpenSSL - editted for style.
 int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
-                                  BIO* in,
+                                  X509* x,
+                                  STACK_OF(X509)* extra_certs,
                                   X509** cert,
                                   X509** issuer) {
-  int ret = 0;
-  X509* x = nullptr;
+  CHECK_EQ(*issuer, nullptr);
+  CHECK_EQ(*cert, nullptr);
 
-  x = PEM_read_bio_X509_AUX(in, nullptr, CryptoPemCallback, nullptr);
-
-  if (x == nullptr) {
-    SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
-    goto end;
-  }
-
-  ret = SSL_CTX_use_certificate(ctx, x);
+  int ret = SSL_CTX_use_certificate(ctx, x);
 
   if (ret) {
     // If we could set up our certificate, now proceed to
     // the CA certificates.
-    X509 *ca;
     int r;
-    unsigned long err;
 
     if (ctx->extra_certs != nullptr) {
       sk_X509_pop_free(ctx->extra_certs, X509_free);
       ctx->extra_certs = nullptr;
     }
 
-    while ((ca = PEM_read_bio_X509(in, nullptr, CryptoPemCallback, nullptr))) {
+    for (int i = 0; i < sk_X509_num(extra_certs); i++) {
+      X509* ca = sk_X509_value(extra_certs, i);
+
       // NOTE: Increments reference count on `ca`
       r = SSL_CTX_add1_chain_cert(ctx, ca);
 
       if (!r) {
-        X509_free(ca);
         ret = 0;
+        *issuer = nullptr;
         goto end;
       }
       // Note that we must not free r if it was successfully
@@ -567,17 +556,8 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
       // Find issuer
       if (*issuer != nullptr || X509_check_issued(ca, x) != X509_V_OK)
         continue;
-      *issuer = ca;
-    }
 
-    // When the while loop ends, it's usually just EOF.
-    err = ERR_peek_last_error();
-    if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
-        ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
-      ERR_clear_error();
-    } else  {
-      // some real error
-      ret = 0;
+      *issuer = ca;
     }
   }
 
@@ -590,13 +570,88 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
       // no need to free `store`
     } else {
       // Increment issuer reference count
-      CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
+      *issuer = X509_dup(*issuer);
+      if (*issuer == nullptr) {
+        ret = 0;
+        goto end;
+      }
     }
   }
 
  end:
+  if (ret && x != nullptr) {
+    *cert = X509_dup(x);
+    if (*cert == nullptr)
+      ret = 0;
+  }
+  return ret;
+}
+
+
+// Read a file that contains our certificate in "PEM" format,
+// possibly followed by a sequence of CA certificates that should be
+// sent to the peer in the Certificate message.
+//
+// Taken from OpenSSL - edited for style.
+int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
+                                  BIO* in,
+                                  X509** cert,
+                                  X509** issuer) {
+  X509* x = nullptr;
+
+  // Just to ensure that `ERR_peek_last_error` below will return only errors
+  // that we are interested in
+  ERR_clear_error();
+
+  x = PEM_read_bio_X509_AUX(in, nullptr, CryptoPemCallback, nullptr);
+
+  if (x == nullptr) {
+    SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
+    return 0;
+  }
+
+  X509* extra = nullptr;
+  int ret = 0;
+  unsigned long err = 0;
+
+  // Read extra certs
+  STACK_OF(X509)* extra_certs = sk_X509_new_null();
+  if (extra_certs == nullptr) {
+    SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_MALLOC_FAILURE);
+    goto done;
+  }
+
+  while ((extra = PEM_read_bio_X509(in, nullptr, CryptoPemCallback, nullptr))) {
+    if (sk_X509_push(extra_certs, extra))
+      continue;
+
+    // Failure, free all certs
+    goto done;
+  }
+  extra = nullptr;
+
+  // When the while loop ends, it's usually just EOF.
+  err = ERR_peek_last_error();
+  if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
+      ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
+    ERR_clear_error();
+  } else  {
+    // some real error
+    goto done;
+  }
+
+  ret = SSL_CTX_use_certificate_chain(ctx, x, extra_certs, cert, issuer);
+  if (!ret)
+    goto done;
+
+ done:
+  if (extra_certs != nullptr)
+    sk_X509_pop_free(extra_certs, X509_free);
+  if (extra != nullptr)
+    X509_free(extra);
   if (x != nullptr)
-    *cert = x;
+    X509_free(x);
+
   return ret;
 }
 
@@ -614,6 +669,16 @@ void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
   if (!bio)
     return;
 
+  // Free previous certs
+  if (sc->issuer_ != nullptr) {
+    X509_free(sc->issuer_);
+    sc->issuer_ = nullptr;
+  }
+  if (sc->cert_ != nullptr) {
+    X509_free(sc->cert_);
+    sc->cert_ = nullptr;
+  }
+
   int rv = SSL_CTX_use_certificate_chain(sc->ctx_,
                                          bio,
                                          &sc->cert_,
@@ -888,7 +953,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
   PKCS12* p12 = nullptr;
   EVP_PKEY* pkey = nullptr;
   X509* cert = nullptr;
-  STACK_OF(X509)* extraCerts = nullptr;
+  STACK_OF(X509)* extra_certs = nullptr;
   char* pass = nullptr;
   bool ret = false;
 
@@ -913,28 +978,33 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
     pass[passlen] = '\0';
   }
 
+  // Free previous certs
+  if (sc->issuer_ != nullptr) {
+    X509_free(sc->issuer_);
+    sc->issuer_ = nullptr;
+  }
+  if (sc->cert_ != nullptr) {
+    X509_free(sc->cert_);
+    sc->cert_ = nullptr;
+  }
+
   if (d2i_PKCS12_bio(in, &p12) &&
-      PKCS12_parse(p12, pass, &pkey, &cert, &extraCerts) &&
-      SSL_CTX_use_certificate(sc->ctx_, cert) &&
+      PKCS12_parse(p12, pass, &pkey, &cert, &extra_certs) &&
+      SSL_CTX_use_certificate_chain(sc->ctx_,
+                                    cert,
+                                    extra_certs,
+                                    &sc->cert_,
+                                    &sc->issuer_) &&
       SSL_CTX_use_PrivateKey(sc->ctx_, pkey)) {
-    // set extra certs
-    while (X509* x509 = sk_X509_pop(extraCerts)) {
-      if (!sc->ca_store_) {
-        sc->ca_store_ = X509_STORE_new();
-        SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
-      }
-
-      X509_STORE_add_cert(sc->ca_store_, x509);
-      SSL_CTX_add_client_CA(sc->ctx_, x509);
-      X509_free(x509);
-    }
+    ret = true;
+  }
 
+  if (pkey != nullptr)
     EVP_PKEY_free(pkey);
+  if (cert != nullptr)
     X509_free(cert);
-    sk_X509_free(extraCerts);
-
-    ret = true;
-  }
+  if (extra_certs != nullptr)
+    sk_X509_free(extra_certs);
 
   PKCS12_free(p12);
   BIO_free_all(in);
diff --git a/test/fixtures/keys/Makefile b/test/fixtures/keys/Makefile
index 143986274a6b93..1148e529cd9595 100644
--- a/test/fixtures/keys/Makefile
+++ b/test/fixtures/keys/Makefile
@@ -79,6 +79,14 @@ agent1-cert.pem: agent1-csr.pem ca1-cert.pem ca1-key.pem
 		-CAcreateserial \
 		-out agent1-cert.pem
 
+agent1-pfx.pem: agent1-cert.pem agent1-key.pem ca1-cert.pem
+	openssl pkcs12 -export \
+		-in agent1-cert.pem \
+		-inkey agent1-key.pem \
+		-certfile ca1-cert.pem \
+		-out agent1-pfx.pem \
+		-password pass:sample
+
 agent1-verify: agent1-cert.pem ca1-cert.pem
 	openssl verify -CAfile ca1-cert.pem agent1-cert.pem
 
diff --git a/test/fixtures/keys/agent1-pfx.pem b/test/fixtures/keys/agent1-pfx.pem
new file mode 100644
index 0000000000000000000000000000000000000000..a36e746a72e06e8dd913f335c1e889ae7646513e
GIT binary patch
literal 2437
zcmY+FX*3j!8pq8T!w^H33`WS<Duyg0B8E4zl(Fwpl9BA$w;?hZ%gc<&2(LA3WG9)y
zSQ8a8$nLcyYgx+GIrrZ8-Ve`t&iVb%^L+ZB^F!hwQ9uAA5(l{fhRDR~#eQc8FauuT
zASe(HqIimtNE}%1p9uT{2NpR+LO=k+>Eit-0U(9ItpEOS1^`BKfLNNlr?OJ1>&rkO
z3qvH1X(dN!wDhm`p>`5<xDYNUtxf=>u2ycJP<hKWPV}79C8o;-r+NhhMo0V46`Z@}
z%gFF>%BvjJ|M6vKhd;iYzes8nQ|!joljb<feHY^J+I++ySM%BEV5jS>@5azgeWC}Z
z&F_;+#ve_b0>Q#cx75wAv&P%l*yy0F^DM6)tq0GSx^4ui4Ne&udX}a~CPGT*!kk^U
zl>Euzs|^nx_e+f0$Gk!N9!3~744Dv^U$~`P!0x_Z7g}{4Nq@>w(WzfAaG0;`xpX)O
z;+hNQfx_rI0#h+8m9<Zr<#{g}w|ib@ZY;tj$l~UO$=A0UoT@+Her|qYuH^gA^1Rmt
z^<!)MEYX&jlnaXyRvcDz>pd=)bbrRQ``^A-i43*mHg-#4;<-~*K#5_RS{}2ceqX1v
zEdc9_Pf0sxcZ-pSm?l;2%x>AZ59gDfU$86)c~C`I_SSaI6$}|-uD0)%FUW5F#8~1H
zOe+RPr&*^=Ux`akQ|FS9Sb#p^kjyYC<K_&4iTdT^Ct1Jtn~k$G4sZH|)b1<g$P6Wb
z<o4|zq5Jsaw`Vy)R+PoI+XvI`gdhg5VR7XFq6d&}RL~(Esz!>3cA>asIgTzJno6jl
znyu8@xmgxn24cp?I(1V584w;%%xrI8TMNs-mnm#TvNcQ@KaSTuRxchYM*q4+by67)
zdi}$4(o>ABONd6$JuLNP#<5snxAl_)FE$PYCXNQlrrg?mCyeyAsf=+y-z-i~*h84f
zx+yw};9aZAeRp(f$&K^yHOj)9Gd(3q-dOg~CBKEf6lXpAT`HHMx-hEnHac5x{+sYS
zc=IrWcujqxEsZV!b+R}4XnC@uUF#l{?fhq%foxab+A%*~$z3CPoCa!S@j-m&6@X5k
z+|mED=-a_t3l^zt)Yp3pW3|RgFf`nArD=0rDbII=j=vG$miY=^r^H(GfDrM%;-p5~
zc#^%mG26rS*RH`1*$Q4K)G}}r@xG;KO2stAr6^5txq}oOVLROQckwR^{+)AL#lg>Y
zxE$X(v28SMg5*lWnAr5;jt3$oED)Ij1poDQ-`IMG*)$6*Je2}Z9{f3|xkXZVwi8cT
zSbp0kaSkp;L+<Dv*mrYfo}5wY(^?rDlTyv!DY=`GsZ!@|us(diUWJ)Pht6k6?WV=X
zM?$eyTS>+^o3oUta9nuFjR7%APeWXx>Im)Slg6xdo~z#`qp7*|!eNn<jc*=SS6a(r
zV(4a*=&2XMas5ji0o6Kp*fu@a%Mjz|xi;w^Ki@W07Lzhe7#Zp0xmQj#9h+J9qUMF5
z1f@AfD+t<Rywy(S$qB!#`*`?#hL3%gE)6fkhdw-2^d@Ua4~9X~1WSDPiE>w%6&j3y
zH+)5+Wa`pm>p|RALeA_L5kDqY)jFlIXB7Na#hz$?+aPD2C&hMX6anA?GD90yaX8Im
zn8>A^FJq-u)cW#P>1{X<(GcrK{AsYL?hfefg^?WUTEmwurQHziYYr;xoA<sOrXOSJ
zza}n=^}^C~4Oy*(I}k^$L`+rP_FkDBS139oz`WRyI??l1WoU<YI2*fCIDY6gszoHP
zr>5<E_1F@*KdpK5)g_!g_U$*@VL*Pj^4y|_B(ZONJv2jW9(TU5%OG8nLdIP;T9_$$
zxmQLDUyQ1<$hh-RZ)+9?3?h7SR=a(`X2xNp@L)M(;KA7i1DgB~otfyVd|k?g<76L(
zyHM4A3PA-E&s3dutk@@T#;-qiN^O$+-K7B8{6k5p&I$1!i*crQTg`iVx|k^m4R4YS
zqu0y7URoT!!s0hqoM#d(LLIsrlPuwpEs2-%4aP~6BO2}zKi%`@r*^HPq5E0V;P+o|
zj%DF7_-%n!X*7G=6<ZcGU`^WR{DI<|6aPPb&oL-w)7o}F623cdi8UzruQsQnNoUwz
z(E;2#-f<@3B~G&o*Tw@<2%m4wj$q_zd!`1T58z95orxpL?v;LlFbOQr^tA^X^oBB+
z$}V6HqKh9!;(!PLBZe0^;3^0QTsp;br!x&^`;R7A0l?F+=oIGvpFJ3V+v7D>0hwOY
z<@wtlr{|HmUV6&+uf97gwyDPcDXYNDM?7aEyDAp_GWzcXXlKLLP=s>)WaVbuk(5#Z
zt*(;X^4um%Kf}k;oTojk!!m>X%N>|6DKpqb@kMZaWF<;X33>Ewriz?}BB$%XW%nMI
z+p}9|!Wer5t!Y5hAg2jzhe<izZb|dimzcrJad7lCs^KJ}VjnrDmYFxoWbVhwY1rl;
zSaTGmoLURYB!Wuk@1#8}D6IeLQg3b^e3?&I0ya141AWwMTp*ewF;^i8wL82^RT4Zg
ztX#D>AfejVax5H~D~xsUhXp*ce1%y}K2IN|e1fWsBW#73X~+R&$(GPx^ZuW7+UzLQ
zJzCyeRPsG9Ku*Y_w_F{FI;PJV&3u>h84EOM%nhK*|5@7EtOHe>onbsnajAP|yU*{T
zK_oxkZfb{Ab16u}9s5@FY@=QYKKl{P*=-#e0qL}7vkYf%5v2yUP5C829F3sl7|)2u
zt6GaF;!KUMAORP8fhgt8@xd6~J><qWs;+j&SNWlyhod$EI-}iUqt;}Ya$m|@)eWJo
z_FiKG+;q|(f&0Uo3slP+V#O_#+g=jQZf0QDsny&D<s8q;u)mYf+tdX%;~-6RBnJ0f
ztbim0&S$r4wl1jJowT-)iyIbcnA#iKiB<RyLeDhR=ikiIK$5|t*1Elf0er{G41x)U
zA}l9`@C}yruT(CGqLPyBwJgeNK7yTg*?69^f@<T6O|YPCJW*0oWS#PL+ok1$d(2Kx
zc*AI*JvXd}W&#(Lc)W+6<8wb64$9FE{-78oZoRo<A?!cc?I6?Jo~U8RuPm<i=5e&W
z!p#9AMTBvO8T@7;-n*(SwJTR1fxPhFRzrB@`9M5L;H$NZ2~VVbZiNY&4Q9a9H$BUc
z@<>r61k7}igApje!~o(+nE`3(5W?;=yp=dQhfSj=T3y`$v7kO@dNR67MEq{|zW{xI
BfE@q;

literal 0
HcmV?d00001

diff --git a/test/parallel/test-tls-ocsp-callback.js b/test/parallel/test-tls-ocsp-callback.js
index d970b2ab013446..a11be7ac22d1c5 100644
--- a/test/parallel/test-tls-ocsp-callback.js
+++ b/test/parallel/test-tls-ocsp-callback.js
@@ -22,11 +22,7 @@ var constants = require('constants');
 var fs = require('fs');
 var join = require('path').join;
 
-test({ response: false }, function() {
-  test({ response: 'hello world' }, function() {
-    test({ ocsp: false });
-  });
-});
+var pfx = fs.readFileSync(join(common.fixturesDir, 'keys', 'agent1-pfx.pem'));
 
 function test(testOptions, cb) {
 
@@ -47,6 +43,13 @@ function test(testOptions, cb) {
   var ocspResponse;
   var session;
 
+  if (testOptions.pfx) {
+    delete options.key;
+    delete options.cert;
+    options.pfx = testOptions.pfx;
+    options.passphrase = testOptions.passphrase;
+  }
+
   var server = tls.createServer(options, function(cleartext) {
     cleartext.on('error', function(er) {
       // We're ok with getting ECONNRESET in this test, but it's
@@ -106,3 +109,23 @@ function test(testOptions, cb) {
     assert.equal(ocspCount, 1);
   });
 }
+
+var tests = [
+  { response: false },
+  { response: 'hello world' },
+  { ocsp: false }
+];
+
+if (!common.hasFipsCrypto) {
+  tests.push({ pfx: pfx, passphrase: 'sample', response: 'hello pfx' });
+}
+
+function runTests(i) {
+  if (i === tests.length) return;
+
+  test(tests[i], common.mustCall(function() {
+    runTests(i + 1);
+  }));
+}
+
+runTests(0);

From 569e5eb9bba3e807a148276f43e13fce59bcb660 Mon Sep 17 00:00:00 2001
From: Brian White <mscdex@mscdex.net>
Date: Fri, 18 Dec 2015 01:35:23 -0500
Subject: [PATCH 15/23] test: fix flaky test-net-error-twice
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

On Windows there can exist some race condition where the
notification of the client's `socket.destroy()` isn't received
before the server writes to the socket. This race condition was
more evident/reproducible on a single core system.

This commit fixes the flakiness by waiting until the server's
connection event handler has been called to destroy the client
socket and perform the server socket write.

Fixes: https://github.com/nodejs/node/issues/4057
PR-URL: https://github.com/nodejs/node/pull/4342
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: João Reis <reis@janeasystems.com>
---
 test/parallel/test-net-error-twice.js | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/test/parallel/test-net-error-twice.js b/test/parallel/test-net-error-twice.js
index af92ca93206f18..28e90ddd611ba9 100644
--- a/test/parallel/test-net-error-twice.js
+++ b/test/parallel/test-net-error-twice.js
@@ -1,16 +1,24 @@
 'use strict';
-var common = require('../common');
-var assert = require('assert');
-var net = require('net');
+const common = require('../common');
+const assert = require('assert');
+const net = require('net');
 
-var buf = new Buffer(10 * 1024 * 1024);
+const buf = new Buffer(10 * 1024 * 1024);
 
 buf.fill(0x62);
 
-var errs = [];
+const errs = [];
+var clientSocket;
+var serverSocket;
+
+function ready() {
+  if (clientSocket && serverSocket) {
+    clientSocket.destroy();
+    serverSocket.write(buf);
+  }
+}
 
 var srv = net.createServer(function onConnection(conn) {
-  conn.write(buf);
   conn.on('error', function(err) {
     errs.push(err);
     if (errs.length > 1 && errs[0] === errs[1])
@@ -19,11 +27,14 @@ var srv = net.createServer(function onConnection(conn) {
   conn.on('close', function() {
     srv.unref();
   });
+  serverSocket = conn;
+  ready();
 }).listen(common.PORT, function() {
   var client = net.connect({ port: common.PORT });
 
   client.on('connect', function() {
-    client.destroy();
+    clientSocket = client;
+    ready();
   });
 });
 

From 72b6b4f70c31656897a546fb3d86b8a98ed8fe36 Mon Sep 17 00:00:00 2001
From: Brian White <mscdex@mscdex.net>
Date: Tue, 15 Dec 2015 03:55:35 -0500
Subject: [PATCH 16/23] module: always decorate thrown errors

This provides more information when encountering a syntax or similar
error when executing a file with require().

Fixes: https://github.com/nodejs/node/issues/4286
PR-URL: https://github.com/nodejs/node/pull/4287
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
---
 lib/internal/util.js                          | 10 +++++--
 lib/module.js                                 | 14 +++++++--
 src/env.h                                     |  3 +-
 src/node.cc                                   | 14 +++++++--
 src/node_util.cc                              | 16 ++++++++++
 .../test-util-decorate-error-stack.js         | 30 ++++++++++++++++---
 test/parallel/test-util-internal.js           | 20 ++++++++++++-
 7 files changed, 94 insertions(+), 13 deletions(-)

diff --git a/lib/internal/util.js b/lib/internal/util.js
index c34682ed1b3809..f7f07cd224f759 100644
--- a/lib/internal/util.js
+++ b/lib/internal/util.js
@@ -4,6 +4,7 @@ const binding = process.binding('util');
 const prefix = '(node) ';
 
 exports.getHiddenValue = binding.getHiddenValue;
+exports.setHiddenValue = binding.setHiddenValue;
 
 // All the internal deprecations have to use this function only, as this will
 // prepend the prefix to the actual message.
@@ -59,13 +60,16 @@ exports._deprecate = function(fn, msg) {
 };
 
 exports.decorateErrorStack = function decorateErrorStack(err) {
-  if (!(exports.isError(err) && err.stack))
+  if (!(exports.isError(err) && err.stack) ||
+      exports.getHiddenValue(err, 'node:decorated') === true)
     return;
 
-  const arrow = exports.getHiddenValue(err, 'arrowMessage');
+  const arrow = exports.getHiddenValue(err, 'node:arrowMessage');
 
-  if (arrow)
+  if (arrow) {
     err.stack = arrow + err.stack;
+    exports.setHiddenValue(err, 'node:decorated', true);
+  }
 };
 
 exports.isError = function isError(e) {
diff --git a/lib/module.js b/lib/module.js
index 8feba15b0fe7c0..82b1971e8bf009 100644
--- a/lib/module.js
+++ b/lib/module.js
@@ -23,6 +23,16 @@ function hasOwnProperty(obj, prop) {
 }
 
 
+function tryWrapper(wrapper, opts) {
+  try {
+    return runInThisContext(wrapper, opts);
+  } catch (e) {
+    internalUtil.decorateErrorStack(e);
+    throw e;
+  }
+}
+
+
 function Module(id, parent) {
   this.id = id;
   this.exports = {};
@@ -371,8 +381,8 @@ Module.prototype._compile = function(content, filename) {
   // create wrapper function
   var wrapper = Module.wrap(content);
 
-  var compiledWrapper = runInThisContext(wrapper,
-                                      { filename: filename, lineOffset: 0 });
+  var compiledWrapper = tryWrapper(wrapper,
+                                   { filename: filename, lineOffset: 0 });
   if (global.v8debug) {
     if (!resolvedArgv) {
       // we enter the repl if we're not given a filename argument.
diff --git a/src/env.h b/src/env.h
index 6151c57069ad7b..743bf057e8584d 100644
--- a/src/env.h
+++ b/src/env.h
@@ -51,7 +51,7 @@ namespace node {
   V(alpn_buffer_string, "alpnBuffer")                                         \
   V(args_string, "args")                                                      \
   V(argv_string, "argv")                                                      \
-  V(arrow_message_string, "arrowMessage")                                     \
+  V(arrow_message_string, "node:arrowMessage")                                \
   V(async, "async")                                                           \
   V(async_queue_string, "_asyncQueue")                                        \
   V(atime_string, "atime")                                                    \
@@ -71,6 +71,7 @@ namespace node {
   V(cwd_string, "cwd")                                                        \
   V(debug_port_string, "debugPort")                                           \
   V(debug_string, "debug")                                                    \
+  V(decorated_string, "node:decorated")                                       \
   V(dest_string, "dest")                                                      \
   V(detached_string, "detached")                                              \
   V(dev_string, "dev")                                                        \
diff --git a/src/node.cc b/src/node.cc
index f9797e664ef937..894c8f76416275 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -1399,6 +1399,15 @@ ssize_t DecodeWrite(Isolate* isolate,
   return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr);
 }
 
+bool IsExceptionDecorated(Environment* env, Local<Value> er) {
+  if (!er.IsEmpty() && er->IsObject()) {
+    Local<Object> err_obj = er.As<Object>();
+    Local<Value> decorated = err_obj->GetHiddenValue(env->decorated_string());
+    return !decorated.IsEmpty() && decorated->IsTrue();
+  }
+  return false;
+}
+
 void AppendExceptionLine(Environment* env,
                          Local<Value> er,
                          Local<Message> message) {
@@ -1508,6 +1517,7 @@ static void ReportException(Environment* env,
 
   Local<Value> trace_value;
   Local<Value> arrow;
+  const bool decorated = IsExceptionDecorated(env, er);
 
   if (er->IsUndefined() || er->IsNull()) {
     trace_value = Undefined(env->isolate());
@@ -1522,7 +1532,7 @@ static void ReportException(Environment* env,
 
   // range errors have a trace member set to undefined
   if (trace.length() > 0 && !trace_value->IsUndefined()) {
-    if (arrow.IsEmpty() || !arrow->IsString()) {
+    if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
       PrintErrorString("%s\n", *trace);
     } else {
       node::Utf8Value arrow_string(env->isolate(), arrow);
@@ -1554,7 +1564,7 @@ static void ReportException(Environment* env,
       node::Utf8Value name_string(env->isolate(), name);
       node::Utf8Value message_string(env->isolate(), message);
 
-      if (arrow.IsEmpty() || !arrow->IsString()) {
+      if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
         PrintErrorString("%s: %s\n", *name_string, *message_string);
       } else {
         node::Utf8Value arrow_string(env->isolate(), arrow);
diff --git a/src/node_util.cc b/src/node_util.cc
index 1e0f214ae4470a..8475468c1f4afe 100644
--- a/src/node_util.cc
+++ b/src/node_util.cc
@@ -52,6 +52,21 @@ static void GetHiddenValue(const FunctionCallbackInfo<Value>& args) {
   args.GetReturnValue().Set(obj->GetHiddenValue(name));
 }
 
+static void SetHiddenValue(const FunctionCallbackInfo<Value>& args) {
+  Environment* env = Environment::GetCurrent(args);
+
+  if (!args[0]->IsObject())
+    return env->ThrowTypeError("obj must be an object");
+
+  if (!args[1]->IsString())
+    return env->ThrowTypeError("name must be a string");
+
+  Local<Object> obj = args[0].As<Object>();
+  Local<String> name = args[1].As<String>();
+
+  args.GetReturnValue().Set(obj->SetHiddenValue(name, args[2]));
+}
+
 
 void Initialize(Local<Object> target,
                 Local<Value> unused,
@@ -63,6 +78,7 @@ void Initialize(Local<Object> target,
 #undef V
 
   env->SetMethod(target, "getHiddenValue", GetHiddenValue);
+  env->SetMethod(target, "setHiddenValue", SetHiddenValue);
 }
 
 }  // namespace util
diff --git a/test/parallel/test-util-decorate-error-stack.js b/test/parallel/test-util-decorate-error-stack.js
index 24fee56df7b655..f289d52be404d3 100644
--- a/test/parallel/test-util-decorate-error-stack.js
+++ b/test/parallel/test-util-decorate-error-stack.js
@@ -3,6 +3,8 @@
 const common = require('../common');
 const assert = require('assert');
 const internalUtil = require('internal/util');
+const spawnSync = require('child_process').spawnSync;
+const path = require('path');
 
 assert.doesNotThrow(function() {
   internalUtil.decorateErrorStack();
@@ -17,17 +19,37 @@ internalUtil.decorateErrorStack(obj);
 assert.strictEqual(obj.stack, undefined);
 
 // Verify that the stack is decorated when possible
+function checkStack(stack) {
+  const matches = stack.match(/var foo bar;/g);
+  assert.strictEqual(Array.isArray(matches), true);
+  assert.strictEqual(matches.length, 1);
+}
 let err;
+const badSyntaxPath =
+    path.resolve(__dirname, '..', 'fixtures', 'syntax', 'bad_syntax')
+        .replace(/\\/g, '\\\\');
 
 try {
-  require('../fixtures/syntax/bad_syntax');
+  require(badSyntaxPath);
 } catch (e) {
   err = e;
-  assert(!/var foo bar;/.test(err.stack));
-  internalUtil.decorateErrorStack(err);
 }
 
-assert(/var foo bar;/.test(err.stack));
+assert(typeof err, 'object');
+checkStack(err.stack);
+
+// Verify that the stack is only decorated once
+internalUtil.decorateErrorStack(err);
+internalUtil.decorateErrorStack(err);
+checkStack(err.stack);
+
+// Verify that the stack is only decorated once for uncaught exceptions
+const args = [
+  '-e',
+  `require('${badSyntaxPath}')`
+];
+const result = spawnSync(process.argv[0], args, { encoding: 'utf8' });
+checkStack(result.stderr);
 
 // Verify that the stack is unchanged when there is no arrow message
 err = new Error('foo');
diff --git a/test/parallel/test-util-internal.js b/test/parallel/test-util-internal.js
index 9ab883ec8b6dcd..a8f6f239ae48cf 100644
--- a/test/parallel/test-util-internal.js
+++ b/test/parallel/test-util-internal.js
@@ -11,6 +11,12 @@ function getHiddenValue(obj, name) {
   };
 }
 
+function setHiddenValue(obj, name, val) {
+  return function() {
+    internalUtil.setHiddenValue(obj, name, val);
+  };
+}
+
 assert.throws(getHiddenValue(), /obj must be an object/);
 assert.throws(getHiddenValue(null, 'foo'), /obj must be an object/);
 assert.throws(getHiddenValue(undefined, 'foo'), /obj must be an object/);
@@ -21,12 +27,24 @@ assert.throws(getHiddenValue({}, null), /name must be a string/);
 assert.throws(getHiddenValue({}, []), /name must be a string/);
 assert.deepEqual(internalUtil.getHiddenValue({}, 'foo'), undefined);
 
+assert.throws(setHiddenValue(), /obj must be an object/);
+assert.throws(setHiddenValue(null, 'foo'), /obj must be an object/);
+assert.throws(setHiddenValue(undefined, 'foo'), /obj must be an object/);
+assert.throws(setHiddenValue('bar', 'foo'), /obj must be an object/);
+assert.throws(setHiddenValue(85, 'foo'), /obj must be an object/);
+assert.throws(setHiddenValue({}), /name must be a string/);
+assert.throws(setHiddenValue({}, null), /name must be a string/);
+assert.throws(setHiddenValue({}, []), /name must be a string/);
+const obj = {};
+assert.strictEqual(internalUtil.setHiddenValue(obj, 'foo', 'bar'), true);
+assert.strictEqual(internalUtil.getHiddenValue(obj, 'foo'), 'bar');
+
 let arrowMessage;
 
 try {
   require('../fixtures/syntax/bad_syntax');
 } catch (err) {
-  arrowMessage = internalUtil.getHiddenValue(err, 'arrowMessage');
+  arrowMessage = internalUtil.getHiddenValue(err, 'node:arrowMessage');
 }
 
 assert(/bad_syntax\.js:1/.test(arrowMessage));

From 09c9110486e8c34bb53081a62ff0c1001cf73fd5 Mon Sep 17 00:00:00 2001
From: Evan Lucas <evanlucas@me.com>
Date: Wed, 18 Nov 2015 06:59:43 -0600
Subject: [PATCH 17/23] repl: use String#repeat instead of Array#join

String#repeat is quite a bit faster than new Array().join().

PR-URL: https://github.com/nodejs/node/pull/3900
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Roman Reiss <me@silverwind.io>
---
 lib/repl.js | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/repl.js b/lib/repl.js
index 76c7487b7bf3a9..de6f562238314f 100644
--- a/lib/repl.js
+++ b/lib/repl.js
@@ -568,7 +568,8 @@ REPLServer.prototype.displayPrompt = function(preserveCursor) {
   var prompt = this._initialPrompt;
   if (this.bufferedCommand.length) {
     prompt = '...';
-    var levelInd = new Array(this.lines.level.length).join('..');
+    const len = this.lines.level.length ? this.lines.level.length - 1 : 0;
+    const levelInd = '..'.repeat(len);
     prompt += levelInd + ' ';
   }
 
@@ -920,7 +921,8 @@ REPLServer.prototype.memory = function memory(cmd) {
   // save the line so I can do magic later
   if (cmd) {
     // TODO should I tab the level?
-    self.lines.push(new Array(self.lines.level.length).join('  ') + cmd);
+    const len = self.lines.level.length ? self.lines.level.length - 1 : 0;
+    self.lines.push('  '.repeat(len) + cmd);
   } else {
     // I don't want to not change the format too much...
     self.lines.push('');

From dd935c2a5d072f12297c523f4c704067e0017922 Mon Sep 17 00:00:00 2001
From: Claudio Rodriguez <cjrodr@yahoo.com>
Date: Thu, 17 Dec 2015 10:05:45 -0300
Subject: [PATCH 18/23] assert: typed array deepequal performance fix

assert.deepEqual: when actual and expected are typed arrays,
wrap them in a new Buffer each to increase performance
significantly.

PR-URL: https://github.com/nodejs/node/pull/4330
Fixes: https://github.com/nodejs/node/issues/4294
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
---
 .../deepequal-prims-and-objs-big-array.js     | 37 +++++++++++++++++
 .../deepequal-prims-and-objs-big-loop.js      | 30 ++++++++++++++
 benchmark/assert/deepequal-typedarrays.js     | 22 ++++++++++
 lib/assert.js                                 |  5 +++
 .../test-assert-typedarray-deepequal.js       | 41 +++++++++++++++++++
 5 files changed, 135 insertions(+)
 create mode 100644 benchmark/assert/deepequal-prims-and-objs-big-array.js
 create mode 100644 benchmark/assert/deepequal-prims-and-objs-big-loop.js
 create mode 100644 benchmark/assert/deepequal-typedarrays.js
 create mode 100644 test/parallel/test-assert-typedarray-deepequal.js

diff --git a/benchmark/assert/deepequal-prims-and-objs-big-array.js b/benchmark/assert/deepequal-prims-and-objs-big-array.js
new file mode 100644
index 00000000000000..d8d2b57331f7ef
--- /dev/null
+++ b/benchmark/assert/deepequal-prims-and-objs-big-array.js
@@ -0,0 +1,37 @@
+'use strict';
+var common = require('../common.js');
+var assert = require('assert');
+var bench = common.createBenchmark(main, {
+  prim: [
+    null,
+    undefined,
+    'a',
+    1,
+    true,
+    {0: 'a'},
+    [1, 2, 3],
+    new Array([1, 2, 3])
+  ],
+  n: [25]
+});
+
+function main(conf) {
+  var prim = conf.prim;
+  var n = +conf.n;
+  var primArray;
+  var primArrayCompare;
+  var x;
+
+  primArray = new Array();
+  primArrayCompare = new Array();
+  for (x = 0; x < (1e5); x++) {
+    primArray.push(prim);
+    primArrayCompare.push(prim);
+  }
+
+  bench.start();
+  for (x = 0; x < n; x++) {
+    assert.deepEqual(primArray, primArrayCompare);
+  }
+  bench.end(n);
+}
diff --git a/benchmark/assert/deepequal-prims-and-objs-big-loop.js b/benchmark/assert/deepequal-prims-and-objs-big-loop.js
new file mode 100644
index 00000000000000..5f0519bb3b45ad
--- /dev/null
+++ b/benchmark/assert/deepequal-prims-and-objs-big-loop.js
@@ -0,0 +1,30 @@
+'use strict';
+var common = require('../common.js');
+var assert = require('assert');
+var bench = common.createBenchmark(main, {
+  prim: [
+    null,
+    undefined,
+    'a',
+    1,
+    true,
+    {0: 'a'},
+    [1, 2, 3],
+    new Array([1, 2, 3])
+  ],
+  n: [1e5]
+});
+
+function main(conf) {
+  var prim = conf.prim;
+  var n = +conf.n;
+  var x;
+
+  bench.start();
+
+  for (x = 0; x < n; x++) {
+    assert.deepEqual(new Array([prim]), new Array([prim]));
+  }
+
+  bench.end(n);
+}
diff --git a/benchmark/assert/deepequal-typedarrays.js b/benchmark/assert/deepequal-typedarrays.js
new file mode 100644
index 00000000000000..99c13206d7560a
--- /dev/null
+++ b/benchmark/assert/deepequal-typedarrays.js
@@ -0,0 +1,22 @@
+'use strict';
+var common = require('../common.js');
+var assert = require('assert');
+var bench = common.createBenchmark(main, {
+  type: ('Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array ' +
+    'Float32Array Float64Array Uint8ClampedArray').split(' '),
+  n: [1]
+});
+
+function main(conf) {
+  var type = conf.type;
+  var clazz = global[type];
+  var n = +conf.n;
+
+  bench.start();
+  var actual = new clazz(n * 1e6);
+  var expected = new clazz(n * 1e6);
+
+  assert.deepEqual(actual, expected);
+
+  bench.end(n);
+}
diff --git a/lib/assert.js b/lib/assert.js
index 11733493450bdc..3e52ab45f66127 100644
--- a/lib/assert.js
+++ b/lib/assert.js
@@ -170,6 +170,11 @@ function _deepEqual(actual, expected, strict) {
              (expected === null || typeof expected !== 'object')) {
     return strict ? actual === expected : actual == expected;
 
+  // If both values are instances of typed arrays, wrap them in
+  // a Buffer each to increase performance
+  } else if (ArrayBuffer.isView(actual) && ArrayBuffer.isView(expected)) {
+    return compare(new Buffer(actual), new Buffer(expected)) === 0;
+
   // 7.5 For all other Object pairs, including Array objects, equivalence is
   // determined by having the same number of owned properties (as verified
   // with Object.prototype.hasOwnProperty.call), the same set of keys
diff --git a/test/parallel/test-assert-typedarray-deepequal.js b/test/parallel/test-assert-typedarray-deepequal.js
new file mode 100644
index 00000000000000..32748784dfe9a8
--- /dev/null
+++ b/test/parallel/test-assert-typedarray-deepequal.js
@@ -0,0 +1,41 @@
+'use strict';
+
+const common = require('../common');
+const assert = require('assert');
+const a = require('assert');
+
+function makeBlock(f) {
+  var args = Array.prototype.slice.call(arguments, 1);
+  return function() {
+    return f.apply(this, args);
+  };
+}
+
+const equalArrayPairs = [
+  [new Uint8Array(1e5), new Uint8Array(1e5)],
+  [new Uint16Array(1e5), new Uint16Array(1e5)],
+  [new Uint32Array(1e5), new Uint32Array(1e5)],
+  [new Uint8ClampedArray(1e5), new Uint8ClampedArray(1e5)],
+  [new Int8Array(1e5), new Int8Array(1e5)],
+  [new Int16Array(1e5), new Int16Array(1e5)],
+  [new Int32Array(1e5), new Int32Array(1e5)],
+  [new Float32Array(1e5), new Float32Array(1e5)],
+  [new Float64Array(1e5), new Float64Array(1e5)]
+];
+
+const notEqualArrayPairs = [
+  [new Uint8Array(2), new Uint8Array(3)],
+  [new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])],
+  [new Uint8ClampedArray([300, 2, 3]), new Uint8Array([300, 2, 3])]
+];
+
+equalArrayPairs.forEach((arrayPair) => {
+  assert.deepEqual(arrayPair[0], arrayPair[1]);
+});
+
+notEqualArrayPairs.forEach((arrayPair) => {
+  assert.throws(
+    makeBlock(a.deepEqual, arrayPair[0], arrayPair[1]),
+    a.AssertionError
+  );
+});

From 8168669b03f0416860bab822b54e9e99a7bd60d1 Mon Sep 17 00:00:00 2001
From: Dave <dave@jut.io>
Date: Sun, 6 Dec 2015 04:55:02 -0800
Subject: [PATCH 19/23] http: remove excess calls to removeSocket

socket.destroy() triggers a 'close' event from the socket which triggers
the onClose handler of HTTPAgent which calls self.removeSocket(). So by
calling self.removeSocket() prior to socket.destroy() we end up with two
calls to self.removeSocket().

If there are pending requests, removeSocket ends up creating a new socket.
So if there are pending requests, each time a request completes, we tear
down one socket and create two more. So the total number of sockets grows
exponentially and without regard for any maxSockets settings. This was
noticed in https://github.com/nodejs/node/issues/4050. Let's get rid of
the extra calls to removeSocket so we only call it once per completed
request.

PR-URL: https://github.com/nodejs/node/pull/4172
Reviewed-By: Brian White <mscdex@mscdex.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor@indutny.com>
---
 lib/_http_agent.js                            |  2 -
 ...test-http-agent-maxsockets-regress-4050.js | 43 +++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)
 create mode 100644 test/parallel/test-http-agent-maxsockets-regress-4050.js

diff --git a/lib/_http_agent.js b/lib/_http_agent.js
index 305baa2cbd2f03..c6e3ef63bd72af 100644
--- a/lib/_http_agent.js
+++ b/lib/_http_agent.js
@@ -66,7 +66,6 @@ function Agent(options) {
           count += self.sockets[name].length;
 
         if (count > self.maxSockets || freeLen >= self.maxFreeSockets) {
-          self.removeSocket(socket, options);
           socket.destroy();
         } else {
           freeSockets = freeSockets || [];
@@ -78,7 +77,6 @@ function Agent(options) {
           freeSockets.push(socket);
         }
       } else {
-        self.removeSocket(socket, options);
         socket.destroy();
       }
     }
diff --git a/test/parallel/test-http-agent-maxsockets-regress-4050.js b/test/parallel/test-http-agent-maxsockets-regress-4050.js
new file mode 100644
index 00000000000000..1cbe37cf0cc443
--- /dev/null
+++ b/test/parallel/test-http-agent-maxsockets-regress-4050.js
@@ -0,0 +1,43 @@
+'use strict';
+const common = require('../common');
+const assert = require('assert');
+const http = require('http');
+
+const MAX_SOCKETS = 2;
+
+const agent = new http.Agent({
+  keepAlive: true,
+  keepAliveMsecs: 1000,
+  maxSockets: MAX_SOCKETS,
+  maxFreeSockets: 2
+});
+
+const server = http.createServer(function(req, res) {
+  res.end('hello world');
+});
+
+function get(path, callback) {
+  return http.get({
+    host: 'localhost',
+    port: common.PORT,
+    agent: agent,
+    path: path
+  }, callback);
+}
+
+server.listen(common.PORT, function() {
+  var finished = 0;
+  const num_requests = 6;
+  for (var i = 0; i < num_requests; i++) {
+    const request = get('/1', function() {
+    });
+    request.on('response', function() {
+      request.abort();
+      const sockets = agent.sockets[Object.keys(agent.sockets)[0]];
+      assert(sockets.length <= MAX_SOCKETS);
+      if (++finished === num_requests) {
+        server.close();
+      }
+    });
+  }
+});

From 2888ec3d570964c3bbb29e88b5d06e46a55b724e Mon Sep 17 00:00:00 2001
From: Ali Ijaz Sheikh <ofrobots@google.com>
Date: Mon, 21 Dec 2015 12:27:19 -0800
Subject: [PATCH 20/23] src: remove forwards for v8::GC*logueCallback

These types are no longer used in the file and V8 4.9 no longer defines these
types anymore.

PR-URL: https://github.com/nodejs/node/pull/4381
Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl>
---
 src/node_counters.cc | 2 --
 src/node_dtrace.cc   | 2 --
 src/node_lttng.cc    | 2 --
 3 files changed, 6 deletions(-)

diff --git a/src/node_counters.cc b/src/node_counters.cc
index ca05e253199af5..c8d2959091d2d9 100644
--- a/src/node_counters.cc
+++ b/src/node_counters.cc
@@ -11,8 +11,6 @@ namespace node {
 using v8::FunctionCallbackInfo;
 using v8::FunctionTemplate;
 using v8::GCCallbackFlags;
-using v8::GCEpilogueCallback;
-using v8::GCPrologueCallback;
 using v8::GCType;
 using v8::HandleScope;
 using v8::Isolate;
diff --git a/src/node_dtrace.cc b/src/node_dtrace.cc
index 568972bab3f90f..2572bbee585b80 100644
--- a/src/node_dtrace.cc
+++ b/src/node_dtrace.cc
@@ -34,8 +34,6 @@ namespace node {
 using v8::FunctionCallbackInfo;
 using v8::FunctionTemplate;
 using v8::GCCallbackFlags;
-using v8::GCEpilogueCallback;
-using v8::GCPrologueCallback;
 using v8::GCType;
 using v8::HandleScope;
 using v8::Isolate;
diff --git a/src/node_lttng.cc b/src/node_lttng.cc
index 876bcda92f82fa..b70f6ca80983e8 100644
--- a/src/node_lttng.cc
+++ b/src/node_lttng.cc
@@ -29,8 +29,6 @@ namespace node {
 using v8::FunctionCallbackInfo;
 using v8::FunctionTemplate;
 using v8::GCCallbackFlags;
-using v8::GCEpilogueCallback;
-using v8::GCPrologueCallback;
 using v8::GCType;
 using v8::HandleScope;
 using v8::Isolate;

From 1009a82d82228bde5b274a236626f525762982c3 Mon Sep 17 00:00:00 2001
From: Mudit Ameta <zeusdeux@gmail.com>
Date: Wed, 2 Dec 2015 02:19:01 +0530
Subject: [PATCH 21/23] repl: Fixed node repl history edge case.

If the deprecated NODE_REPL_HISTORY_FILE is set to default
node history file path ($HOME/.node_repl_history) and the file
doesn't exist, then node creates the file and then crashes when
it tries to parse that file as JSON thinking that it's an older
JSON formatted history file. This fixes that bug.

This patch also prevents node repl from throwing if the old
history file is empty or if $HOME/.node_repl_history is empty.

Fixes: https://github.com/nodejs/node/issues/4102
PR-URL: https://github.com/nodejs/node/pull/4108
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
---
 lib/internal/repl.js                          | 18 ++++++++++++++++--
 test/fixtures/.empty-repl-history-file        |  0
 test/parallel/test-repl-persistent-history.js | 16 +++++++++++++++-
 3 files changed, 31 insertions(+), 3 deletions(-)
 create mode 100644 test/fixtures/.empty-repl-history-file

diff --git a/lib/internal/repl.js b/lib/internal/repl.js
index 1a62414a49e95d..79ad79abe87f04 100644
--- a/lib/internal/repl.js
+++ b/lib/internal/repl.js
@@ -120,7 +120,15 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) {
 
     if (data) {
       repl.history = data.split(/[\n\r]+/, repl.historySize);
-    } else if (oldHistoryPath) {
+    } else if (oldHistoryPath === historyPath) {
+      // If pre-v3.0, the user had set NODE_REPL_HISTORY_FILE to
+      // ~/.node_repl_history, warn the user about it and proceed.
+      repl._writeToOutput(
+          '\nThe old repl history file has the same name and location as ' +
+          `the new one i.e., ${historyPath} and is empty.\nUsing it as is.\n`);
+      repl._refreshLine();
+
+    }  else if (oldHistoryPath) {
       // Grab data from the older pre-v3.0 JSON NODE_REPL_HISTORY_FILE format.
       repl._writeToOutput(
           '\nConverting old JSON repl history to line-separated history.\n' +
@@ -128,7 +136,13 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) {
       repl._refreshLine();
 
       try {
-        repl.history = JSON.parse(fs.readFileSync(oldHistoryPath, 'utf8'));
+        // Pre-v3.0, repl history was stored as JSON.
+        // Try and convert it to line separated history.
+        const oldReplJSONHistory = fs.readFileSync(oldHistoryPath, 'utf8');
+
+        // Only attempt to use the history if there was any.
+        if (oldReplJSONHistory) repl.history = JSON.parse(oldReplJSONHistory);
+
         if (!Array.isArray(repl.history)) {
           throw new Error('Expected array, got ' + typeof repl.history);
         }
diff --git a/test/fixtures/.empty-repl-history-file b/test/fixtures/.empty-repl-history-file
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/test/parallel/test-repl-persistent-history.js b/test/parallel/test-repl-persistent-history.js
index 10e0dedf53ec3e..9b4b3890aed6cb 100644
--- a/test/parallel/test-repl-persistent-history.js
+++ b/test/parallel/test-repl-persistent-history.js
@@ -66,6 +66,10 @@ const homedirErr = '\nError: Could not get the home directory.\n' +
                    'REPL session history will not be persisted.\n';
 const replFailedRead = '\nError: Could not open history file.\n' +
                        'REPL session history will not be persisted.\n';
+const sameHistoryFilePaths = '\nThe old repl history file has the same name ' +
+                             'and location as the new one i.e., ' +
+                             path.join(common.tmpDir, '.node_repl_history') +
+                             ' and is empty.\nUsing it as is.\n';
 // File paths
 const fixtures = path.join(common.testDir, 'fixtures');
 const historyFixturePath = path.join(fixtures, '.node_repl_history');
@@ -73,9 +77,9 @@ const historyPath = path.join(common.tmpDir, '.fixture_copy_repl_history');
 const historyPathFail = path.join(common.tmpDir, '.node_repl\u0000_history');
 const oldHistoryPath = path.join(fixtures, 'old-repl-history-file.json');
 const enoentHistoryPath = path.join(fixtures, 'enoent-repl-history-file.json');
+const emptyHistoryPath = path.join(fixtures, '.empty-repl-history-file');
 const defaultHistoryPath = path.join(common.tmpDir, '.node_repl_history');
 
-
 const tests = [{
   env: { NODE_REPL_HISTORY: '' },
   test: [UP],
@@ -93,6 +97,16 @@ const tests = [{
   test: [UP],
   expected: [prompt, replDisabled, prompt]
 },
+{
+  env: { NODE_REPL_HISTORY_FILE: emptyHistoryPath },
+  test: [UP],
+  expected: [prompt, convertMsg, prompt]
+},
+{
+  env: { NODE_REPL_HISTORY_FILE: defaultHistoryPath },
+  test: [UP],
+  expected: [prompt, sameHistoryFilePaths, prompt]
+},
 {
   env: { NODE_REPL_HISTORY: historyPath },
   test: [UP, CLEAR],

From b7fd395b3b3dedf0deec4b6a845345ec49291d54 Mon Sep 17 00:00:00 2001
From: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Date: Tue, 22 Dec 2015 16:00:39 -0500
Subject: [PATCH 22/23] 2015-12-22, Version 5.3.1 (Stable)

Notable changes:

* general: Several minor performance improvements:
  - lib: Use arrow functions instead of bind where possible (Minwoo
Jung) https://github.com/nodejs/node/pull/3622
  - node: Improved accessor perf of process.env (Trevor Norris)
https://github.com/nodejs/node/pull/3780
  - **node**: Improved performance of hrtime() (Trevor Norris)
https://github.com/nodejs/node/pull/3780
  - node: Improved GetActiveHandles performance (Trevor Norris)
https://github.com/nodejs/node/pull/3780
* module: Errors during require() now provide more information (Brian
White) https://github.com/nodejs/node/pull/4287
---
 CHANGELOG.md       | 42 ++++++++++++++++++++++++++++++++++++++++++
 src/node_version.h |  2 +-
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index cb3a1744cca853..1704513f21d1ab 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,47 @@
 # Node.js ChangeLog
 
+## 2015-12-22, Version 5.3.1 (Stable), @Fishrock123
+
+### Notable changes
+
+* **general**: Several minor performance improvements:
+  - **lib**: Use arrow functions instead of bind where possible (Minwoo Jung) [nodejs/node#3622](https://github.com/nodejs/node/pull/3622).
+  - **node**: Improved accessor perf of `process.env` (Trevor Norris) [nodejs/node#3780](https://github.com/nodejs/node/pull/3780).
+  - **node**: Improved performance of `hrtime()` (Trevor Norris) [nodejs/node#3780](https://github.com/nodejs/node/pull/3780).
+  - **node**: Improved GetActiveHandles performance (Trevor Norris) [nodejs/node#3780](https://github.com/nodejs/node/pull/3780).
+* **module**: Errors during `require()` now provide more information (Brian White) [nodejs/node#4287](https://github.com/nodejs/node/pull/4287).
+
+### Known issues
+
+* Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690)
+* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894)
+* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435).
+* Unicode characters in filesystem paths are not handled consistently across platforms or Node.js APIs. See [#2088](https://github.com/nodejs/node/issues/2088), [#3401](https://github.com/nodejs/node/issues/3401) and [#3519](https://github.com/nodejs/node/issues/3519).
+
+### Commits
+
+* [[`dd935c2a5d`](https://github.com/v5.3.0/HEAD/commit/dd935c2a5d)] - **assert**: typed array deepequal performance fix (Claudio Rodriguez) [nodejs/node#4330](https://github.com/nodejs/node/pull/4330)
+* [[`6406dbb4b2`](https://github.com/v5.3.0/HEAD/commit/6406dbb4b2)] - **crypto**: load PFX chain the same way as regular one (Fedor Indutny) [nodejs/node#4165](https://github.com/nodejs/node/pull/4165)
+* [[`1a07eabe7b`](https://github.com/v5.3.0/HEAD/commit/1a07eabe7b)] - **debugger**: guard against call from non-node context (Ben Noordhuis) [nodejs/node#4328](https://github.com/nodejs/node/pull/4328)
+* [[`46c44c830f`](https://github.com/v5.3.0/HEAD/commit/46c44c830f)] - **doc**: fix, modernize examples in docs (James M Snell) [nodejs/node#4282](https://github.com/nodejs/node/pull/4282)
+* [[`1dd09a8fba`](https://github.com/v5.3.0/HEAD/commit/1dd09a8fba)] - **doc**: Typo in buffer.markdown referencing buf.write() (chrisjohn404) [nodejs/node#4324](https://github.com/nodejs/node/pull/4324)
+* [[`8c718543ad`](https://github.com/v5.3.0/HEAD/commit/8c718543ad)] - **doc**: fix link in addons.markdown (Nicholas Young) [nodejs/node#4331](https://github.com/nodejs/node/pull/4331)
+* [[`3f19d4a320`](https://github.com/v5.3.0/HEAD/commit/3f19d4a320)] - **fs**: use pushValueToArray for readdir(Sync) (Trevor Norris) [nodejs/node#3780](https://github.com/nodejs/node/pull/3780)
+* [[`8168669b03`](https://github.com/v5.3.0/HEAD/commit/8168669b03)] - **http**: remove excess calls to removeSocket (Dave) [nodejs/node#4172](https://github.com/nodejs/node/pull/4172)
+* [[`645577f55f`](https://github.com/v5.3.0/HEAD/commit/645577f55f)] - **http**: Remove an unnecessary assignment (Bo Borgerson) [nodejs/node#4323](https://github.com/nodejs/node/pull/4323)
+* [[`369f795132`](https://github.com/v5.3.0/HEAD/commit/369f795132)] - **http_parser**: use pushValueToArray for headers (Trevor Norris) [nodejs/node#3780](https://github.com/nodejs/node/pull/3780)
+* [[`7435491fab`](https://github.com/v5.3.0/HEAD/commit/7435491fab)] - **lib**: use arrow functions instead of bind (Minwoo Jung) [nodejs/node#3622](https://github.com/nodejs/node/pull/3622)
+* [[`72b6b4f70c`](https://github.com/v5.3.0/HEAD/commit/72b6b4f70c)] - **module**: always decorate thrown errors (Brian White) [nodejs/node#4287](https://github.com/nodejs/node/pull/4287)
+* [[`e80865835f`](https://github.com/v5.3.0/HEAD/commit/e80865835f)] - **node**: improve accessor perf of process.env (Trevor Norris) [nodejs/node#3780](https://github.com/nodejs/node/pull/3780)
+* [[`b73bb71ab4`](https://github.com/v5.3.0/HEAD/commit/b73bb71ab4)] - **node**: improve performance of hrtime() (Trevor Norris) [nodejs/node#3780](https://github.com/nodejs/node/pull/3780)
+* [[`4f078661f3`](https://github.com/v5.3.0/HEAD/commit/4f078661f3)] - **node**: improve GetActiveHandles performance (Trevor Norris) [nodejs/node#3780](https://github.com/nodejs/node/pull/3780)
+* [[`89c32bc491`](https://github.com/v5.3.0/HEAD/commit/89c32bc491)] - **node**: fix erroneously named function call (Trevor Norris) [nodejs/node#3780](https://github.com/nodejs/node/pull/3780)
+* [[`1009a82d82`](https://github.com/v5.3.0/HEAD/commit/1009a82d82)] - **repl**: Fixed node repl history edge case. (Mudit Ameta) [nodejs/node#4108](https://github.com/nodejs/node/pull/4108)
+* [[`09c9110486`](https://github.com/v5.3.0/HEAD/commit/09c9110486)] - **repl**: use String#repeat instead of Array#join (Evan Lucas) [nodejs/node#3900](https://github.com/nodejs/node/pull/3900)
+* [[`2888ec3d57`](https://github.com/v5.3.0/HEAD/commit/2888ec3d57)] - **src**: remove forwards for v8::GC*logueCallback (Ali Ijaz Sheikh) [nodejs/node#4381](https://github.com/nodejs/node/pull/4381)
+* [[`569e5eb9bb`](https://github.com/v5.3.0/HEAD/commit/569e5eb9bb)] - **test**: fix flaky test-net-error-twice (Brian White) [nodejs/node#4342](https://github.com/nodejs/node/pull/4342)
+* [[`d187c6e800`](https://github.com/v5.3.0/HEAD/commit/d187c6e800)] - **test**: try other ipv6 localhost alternatives (Brian White) [nodejs/node#4325](https://github.com/nodejs/node/pull/4325)
+
 ## 2015-12-16, Version 5.3.0 (Stable), @cjihrig
 
 ### Notable changes
diff --git a/src/node_version.h b/src/node_version.h
index 763f3e3cf75e0b..505e4d8758b6e5 100644
--- a/src/node_version.h
+++ b/src/node_version.h
@@ -5,7 +5,7 @@
 #define NODE_MINOR_VERSION 3
 #define NODE_PATCH_VERSION 1
 
-#define NODE_VERSION_IS_RELEASE 0
+#define NODE_VERSION_IS_RELEASE 1
 
 #ifndef NODE_STRINGIFY
 #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)

From d3d2216c8835ff244acbd68a693c94867c360b3d Mon Sep 17 00:00:00 2001
From: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Date: Tue, 22 Dec 2015 16:01:32 -0500
Subject: [PATCH 23/23] Working on v5.3.2

---
 src/node_version.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/node_version.h b/src/node_version.h
index 505e4d8758b6e5..9769ab11bb6d16 100644
--- a/src/node_version.h
+++ b/src/node_version.h
@@ -3,9 +3,9 @@
 
 #define NODE_MAJOR_VERSION 5
 #define NODE_MINOR_VERSION 3
-#define NODE_PATCH_VERSION 1
+#define NODE_PATCH_VERSION 2
 
-#define NODE_VERSION_IS_RELEASE 1
+#define NODE_VERSION_IS_RELEASE 0
 
 #ifndef NODE_STRINGIFY
 #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)