Repository: eslint/eslint
Pull request #9328 (2017-09-19 00:26:46)

Fix: special EventEmitter keys leak information about other rules
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request? (put an "X" next to item)**

[x] Bug fix

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

**Tell us about your environment**

* **ESLint Version:** master
* **Node Version:** 8.5.0
* **npm Version:** 5.3.0

**What parser (default, Babel-ESLint, etc.) are you using?**

N/A

**Please show your full configuration:**

N/A

**What did you do? Please include the actual source code causing the issue.**

```js
"use strict";

const eslint = require("eslint");
const linter = new eslint.Linter();

linter.defineRule("foo-rule", context => {
    return {
        newListener() {
            assert(false);
        }
    }
});

linter.verify("foo", { rules: { "foo-rule": "error", "no-undef": "error" } });
```

**What did you expect to happen?**

I expected the `newListener` method to never get called, because there are no nodes with type `newListener`.

**What actually happened? Please include the actual, raw output from ESLint.**

The `newListener` method got called because a listener was added from `no-undef`, and the string `"newListener"` has [special behavior](https://nodejs.org/api/events.html#events_event_newlistener) when added to an event emitter.

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (http://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

**What changes did you make? (Give an overview)**

`Linter` uses Node's `EventEmitter` API to register listeners for rules. However, the `EventEmitter` API has a few problems for this use case:

* `EventEmitter` has three "special" events (`newListener`, `removeListener`, and `error`) which are called when something happens with another listener. This is undesirable because `Linter` allows rules to register listeners for arbitrary string events, and we don't want rule listeners to be able to detect each other.
* `EventEmitter` calls listeners with a `this` value of the event emitter itself. This is undesirable because this would allow rules to modify or tamper with listeners registered by other rules.

This commit fixes the problem by updating `Linter` to use a custom event-emitting object with a similar API, rather than `EventEmitter` itself.

**Is there anything you'd like reviewers to focus on?**

Nothing in particular

eslintbot: LGTM
eslintbot: LGTM
eslintbot: LGTM
eslintbot: LGTM
eslintbot: LGTM
eslintbot: LGTM
eslintbot: LGTM

Patch:
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 16822fd97..e8ad7ffbe 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -3,8 +3,8 @@
 
     This template is for bug reports. If you are reporting a bug, please continue on. If you are here for another reason, please see below:
 
-    1. To propose a new rule: http://eslint.org/docs/developer-guide/contributing/new-rules
-    2. To request a change: http://eslint.org/docs/developer-guide/contributing/changes
+    1. To propose a new rule: https://eslint.org/docs/developer-guide/contributing/new-rules
+    2. To request a change: https://eslint.org/docs/developer-guide/contributing/changes
     3. If you have any questions, please stop by our chatroom: https://gitter.im/eslint/eslint
 
     Note that leaving sections blank will make it difficult for us to troubleshoot and we may have to close the issue.
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 6b7012737..ca5e285ec 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -20,7 +20,7 @@
 <!--
     Please ensure your pull request is ready:
 
-    - Read the pull request guide (http://eslint.org/docs/developer-guide/contributing/pull-requests)
+    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
     - Include tests for this change
     - Update documentation for this change (if appropriate)
 -->
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 363148738..411e7fb52 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -10,16 +10,16 @@ This project adheres to the [JS Foundation Code of Conduct](https://js.foundatio
 
 Before filing an issue, please be sure to read the guidelines for what you're reporting:
 
-* [Bug Report](http://eslint.org/docs/developer-guide/contributing/reporting-bugs)
-* [Propose a New Rule](http://eslint.org/docs/developer-guide/contributing/new-rules)
-* [Proposing a Rule Change](http://eslint.org/docs/developer-guide/contributing/rule-changes)
-* [Request a Change](http://eslint.org/docs/developer-guide/contributing/changes)
+* [Bug Report](https://eslint.org/docs/developer-guide/contributing/reporting-bugs)
+* [Propose a New Rule](https://eslint.org/docs/developer-guide/contributing/new-rules)
+* [Proposing a Rule Change](https://eslint.org/docs/developer-guide/contributing/rule-changes)
+* [Request a Change](https://eslint.org/docs/developer-guide/contributing/changes)
 
 ## Contributing Code
 
-Please sign our [Contributor License Agreement](https://cla.js.foundation/eslint/eslint) and read over the [Pull Request Guidelines](http://eslint.org/docs/developer-guide/contributing/pull-requests).
+Please sign our [Contributor License Agreement](https://cla.js.foundation/eslint/eslint) and read over the [Pull Request Guidelines](https://eslint.org/docs/developer-guide/contributing/pull-requests).
 
 ## Full Documentation
 
 Our full contribution guidelines can be found at:
-http://eslint.org/docs/developer-guide/contributing/
+https://eslint.org/docs/developer-guide/contributing/
diff --git a/README.md b/README.md
index 7304f1b70..9ebf50389 100644
--- a/README.md
+++ b/README.md
@@ -9,11 +9,11 @@
 
 # ESLint
 
-[Website](http://eslint.org) |
-[Configuring](http://eslint.org/docs/user-guide/configuring) |
-[Rules](http://eslint.org/docs/rules/) |
-[Contributing](http://eslint.org/docs/developer-guide/contributing) |
-[Reporting Bugs](http://eslint.org/docs/developer-guide/contributing/reporting-bugs) |
+[Website](https://eslint.org) |
+[Configuring](https://eslint.org/docs/user-guide/configuring) |
+[Rules](https://eslint.org/docs/rules/) |
+[Contributing](https://eslint.org/docs/developer-guide/contributing) |
+[Reporting Bugs](https://eslint.org/docs/developer-guide/contributing/reporting-bugs) |
 [Code of Conduct](https://js.foundation/community/code-of-conduct) |
 [Twitter](https://twitter.com/geteslint) |
 [Mailing List](https://groups.google.com/group/eslint) |
@@ -88,17 +88,17 @@ After running `eslint --init`, you'll have a `.eslintrc` file in your directory.
 }
 ```
 
-The names `"semi"` and `"quotes"` are the names of [rules](http://eslint.org/docs/rules) in ESLint. The first value is the error level of the rule and can be one of these values:
+The names `"semi"` and `"quotes"` are the names of [rules](https://eslint.org/docs/rules) in ESLint. The first value is the error level of the rule and can be one of these values:
 
 * `"off"` or `0` - turn the rule off
 * `"warn"` or `1` - turn the rule on as a warning (doesn't affect exit code)
 * `"error"` or `2` - turn the rule on as an error (exit code will be 1)
 
-The three error levels allow you fine-grained control over how ESLint applies rules (for more configuration options and details, see the [configuration docs](http://eslint.org/docs/user-guide/configuring)).
+The three error levels allow you fine-grained control over how ESLint applies rules (for more configuration options and details, see the [configuration docs](https://eslint.org/docs/user-guide/configuring)).
 
 ## Sponsors
 
-* Site search ([eslint.org](http://eslint.org)) is sponsored by [Algolia](https://www.algolia.com)
+* Site search ([eslint.org](https://eslint.org)) is sponsored by [Algolia](https://www.algolia.com)
 
 ## Team
 
@@ -145,10 +145,10 @@ ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/comm
 
 Before filing an issue, please be sure to read the guidelines for what you're reporting:
 
-* [Bug Report](http://eslint.org/docs/developer-guide/contributing/reporting-bugs)
-* [Propose a New Rule](http://eslint.org/docs/developer-guide/contributing/new-rules)
-* [Proposing a Rule Change](http://eslint.org/docs/developer-guide/contributing/rule-changes)
-* [Request a Change](http://eslint.org/docs/developer-guide/contributing/changes)
+* [Bug Report](https://eslint.org/docs/developer-guide/contributing/reporting-bugs)
+* [Propose a New Rule](https://eslint.org/docs/developer-guide/contributing/new-rules)
+* [Proposing a Rule Change](https://eslint.org/docs/developer-guide/contributing/rule-changes)
+* [Request a Change](https://eslint.org/docs/developer-guide/contributing/changes)
 
 ## Semantic Versioning Policy
 
@@ -195,11 +195,11 @@ Despite being slower, we believe that ESLint is fast enough to replace JSHint wi
 
 ### I heard ESLint is going to replace JSCS?
 
-Yes. Since we are solving the same problems, ESLint and JSCS teams have decided to join forces and work together in the development of ESLint instead of competing with each other. You can read more about this in both [ESLint](http://eslint.org/blog/2016/04/welcoming-jscs-to-eslint) and [JSCS](https://medium.com/@markelog/jscs-end-of-the-line-bc9bf0b3fdb2#.u76sx334n) announcements.
+Yes. Since we are solving the same problems, ESLint and JSCS teams have decided to join forces and work together in the development of ESLint instead of competing with each other. You can read more about this in both [ESLint](https://eslint.org/blog/2016/04/welcoming-jscs-to-eslint) and [JSCS](https://medium.com/@markelog/jscs-end-of-the-line-bc9bf0b3fdb2#.u76sx334n) announcements.
 
 ### So, should I stop using JSCS and start using ESLint?
 
-Maybe, depending on how much you need it. [JSCS has reached end of life](http://eslint.org/blog/2016/07/jscs-end-of-life), but if it is working for you then there is no reason to move yet. We are still working to smooth the transition. You can see our progress [here](https://github.com/eslint/eslint/milestones/JSCS%20Compatibility). We’ll announce when all of the changes necessary to support JSCS users in ESLint are complete and will start encouraging JSCS users to switch to ESLint at that time.
+Maybe, depending on how much you need it. [JSCS has reached end of life](https://eslint.org/blog/2016/07/jscs-end-of-life), but if it is working for you then there is no reason to move yet. We are still working to smooth the transition. You can see our progress [here](https://github.com/eslint/eslint/milestones/JSCS%20Compatibility). We’ll announce when all of the changes necessary to support JSCS users in ESLint are complete and will start encouraging JSCS users to switch to ESLint at that time.
 
 If you are having issues with JSCS, you can try to move to ESLint. We are focusing our time and energy on JSCS compatibility issues.
 
@@ -210,17 +210,17 @@ ESLint does both traditional linting (looking for problematic patterns) and styl
 
 ### Does ESLint support JSX?
 
-Yes, ESLint natively supports parsing JSX syntax (this must be enabled in [configuration](http://eslint.org/docs/user-guide/configuring).). Please note that supporting JSX syntax *is not* the same as supporting React. React applies specific semantics to JSX syntax that ESLint doesn't recognize. We recommend using [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react) if you are using React and want React semantics.
+Yes, ESLint natively supports parsing JSX syntax (this must be enabled in [configuration](https://eslint.org/docs/user-guide/configuring).). Please note that supporting JSX syntax *is not* the same as supporting React. React applies specific semantics to JSX syntax that ESLint doesn't recognize. We recommend using [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react) if you are using React and want React semantics.
 
 ### What about ECMAScript 6 support?
 
-ESLint has full support for ECMAScript 6. By default, this support is off. You can enable ECMAScript 6 syntax and global variables through [configuration](http://eslint.org/docs/user-guide/configuring).
+ESLint has full support for ECMAScript 6. By default, this support is off. You can enable ECMAScript 6 syntax and global variables through [configuration](https://eslint.org/docs/user-guide/configuring).
 
 ### What about experimental features?
 
 ESLint doesn't natively support experimental ECMAScript language features. You can use [babel-eslint](https://github.com/babel/babel-eslint) to use any option available in Babel.
 
-Once a language feature has been adopted into the ECMAScript standard (stage 4 according to the [TC39 process](https://tc39.github.io/process-document/)), we will accept issues and pull requests related to the new feature, subject to our [contributing guidelines](http://eslint.org/docs/developer-guide/contributing). Until then, please use the appropriate parser and plugin(s) for your experimental feature.
+Once a language feature has been adopted into the ECMAScript standard (stage 4 according to the [TC39 process](https://tc39.github.io/process-document/)), we will accept issues and pull requests related to the new feature, subject to our [contributing guidelines](https://eslint.org/docs/developer-guide/contributing). Until then, please use the appropriate parser and plugin(s) for your experimental feature.
 
 ### Where to ask for help?
 
diff --git a/docs/maintainer-guide/issues.md b/docs/maintainer-guide/issues.md
index 4f045513f..780508b30 100644
--- a/docs/maintainer-guide/issues.md
+++ b/docs/maintainer-guide/issues.md
@@ -44,7 +44,7 @@ The steps for triaging an issue are:
     * **Bugs**: See [bug reporting guidelines](/docs/developer-guide/contributing/reporting-bugs)
     * **New Rules:** See [rule proposal guidelines](/docs/developer-guide/contributing/new-rules)
     * **Rule Changes:** See [rule change proposal guidelines](/docs/developer-guide/contributing/rule-changes)
-    * **Other Changes:** See [change proposal guidelines](http://eslint.org/docs/developer-guide/contributing/changes)
+    * **Other Changes:** See [change proposal guidelines](https://eslint.org/docs/developer-guide/contributing/changes)
 1. Next steps:
     * **Questions:** answer the question and close the issue when the conversation is over.
     * **Bugs:** if you can verify the bug, add the "accepted" label and ask if they would like to submit a pull request.
diff --git a/docs/rules/comma-style.md b/docs/rules/comma-style.md
index 30338fdf2..b10663c53 100644
--- a/docs/rules/comma-style.md
+++ b/docs/rules/comma-style.md
@@ -38,7 +38,7 @@ This rule also accepts an additional `exceptions` object:
     * `"ObjectPattern": true` ignores comma style in object patterns of destructuring
     * `"VariableDeclaration": true` ignores comma style in variable declarations
 
-A way to determine the node types as defined by [ESTree](https://github.com/estree/estree) is to use the [online demo](http://eslint.org/parser).
+A way to determine the node types as defined by [ESTree](https://github.com/estree/estree) is to use the [online demo](https://eslint.org/parser).
 
 ### last
 
diff --git a/docs/rules/no-multi-spaces.md b/docs/rules/no-multi-spaces.md
index 340f951ba..f3270cb7d 100644
--- a/docs/rules/no-multi-spaces.md
+++ b/docs/rules/no-multi-spaces.md
@@ -102,7 +102,7 @@ var x = 5;      /* multiline
 
 To avoid contradictions with other rules that require multiple spaces, this rule has an `exceptions` option to ignore certain nodes.
 
-This option is an object that expects property names to be AST node types as defined by [ESTree](https://github.com/estree/estree). The easiest way to determine the node types for `exceptions` is to use the [online demo](http://eslint.org/parser).
+This option is an object that expects property names to be AST node types as defined by [ESTree](https://github.com/estree/estree). The easiest way to determine the node types for `exceptions` is to use the [online demo](https://eslint.org/parser).
 
 Only the `Property` node type is ignored by default, because for the [key-spacing](key-spacing.md) rule some alignment options require multiple spaces in properties of object literals.
 
diff --git a/docs/rules/no-restricted-syntax.md b/docs/rules/no-restricted-syntax.md
index 8efbd780e..37dbe8f01 100644
--- a/docs/rules/no-restricted-syntax.md
+++ b/docs/rules/no-restricted-syntax.md
@@ -2,7 +2,7 @@
 
 JavaScript has a lot of language features, and not everyone likes all of them. As a result, some projects choose to disallow the use of certain language features altogether. For instance, you might decide to disallow the use of `try-catch` or `class`, or you might decide to disallow the use of the `in` operator.
 
-Rather than creating separate rules for every language feature you want to turn off, this rule allows you to configure the syntax elements you want to restrict use of. These elements are represented by their [ESTree](https://github.com/estree/estree) node types. For example, a function declaration is represented by `FunctionDeclaration` and the `with` statement is represented by `WithStatement`. You may find the full list of AST node names you can use [on GitHub](https://github.com/eslint/espree/blob/master/lib/ast-node-types.js) and use the [online parser](http://eslint.org/parser/) to see what type of nodes your code consists of.
+Rather than creating separate rules for every language feature you want to turn off, this rule allows you to configure the syntax elements you want to restrict use of. These elements are represented by their [ESTree](https://github.com/estree/estree) node types. For example, a function declaration is represented by `FunctionDeclaration` and the `with` statement is represented by `WithStatement`. You may find the full list of AST node names you can use [on GitHub](https://github.com/eslint/espree/blob/master/lib/ast-node-types.js) and use the [online parser](https://eslint.org/parser/) to see what type of nodes your code consists of.
 
 You can also specify [AST selectors](../developer-guide/selectors) to restrict, allowing much more precise control over syntax patterns.
 
diff --git a/docs/rules/no-undef.md b/docs/rules/no-undef.md
index ac7c231ae..5d21185a5 100644
--- a/docs/rules/no-undef.md
+++ b/docs/rules/no-undef.md
@@ -75,7 +75,7 @@ if(typeof a === "string"){}
 
 ## Environments
 
-For convenience, ESLint provides shortcuts that pre-define global variables exposed by popular libraries and runtime environments. This rule supports these environments, as listed in [Specifying Environments](http://eslint.org/docs/user-guide/configuring#specifying-environments).  A few examples are given below.
+For convenience, ESLint provides shortcuts that pre-define global variables exposed by popular libraries and runtime environments. This rule supports these environments, as listed in [Specifying Environments](https://eslint.org/docs/user-guide/configuring#specifying-environments).  A few examples are given below.
 
 ### browser
 
diff --git a/docs/rules/padding-line-between-statements.md b/docs/rules/padding-line-between-statements.md
index 8c22b7368..06b0a2172 100644
--- a/docs/rules/padding-line-between-statements.md
+++ b/docs/rules/padding-line-between-statements.md
@@ -221,9 +221,9 @@ foo();
 If you don't want to notify warnings about linebreaks, then it's safe to disable this rule.
 
 
-[lines-around-directive]: http://eslint.org/docs/rules/lines-around-directive
-[newline-after-var]: http://eslint.org/docs/rules/newline-after-var
-[newline-before-return]: http://eslint.org/docs/rules/newline-before-return
+[lines-around-directive]: https://eslint.org/docs/rules/lines-around-directive
+[newline-after-var]: https://eslint.org/docs/rules/newline-after-var
+[newline-before-return]: https://eslint.org/docs/rules/newline-before-return
 [requirePaddingNewLineAfterVariableDeclaration]: http://jscs.info/rule/requirePaddingNewLineAfterVariableDeclaration
 [requirePaddingNewLinesAfterBlocks]: http://jscs.info/rule/requirePaddingNewLinesAfterBlocks
 [disallowPaddingNewLinesAfterBlocks]: http://jscs.info/rule/disallowPaddingNewLinesAfterBlocks
diff --git a/docs/rules/prefer-promise-reject-errors.md b/docs/rules/prefer-promise-reject-errors.md
index af0f9bd87..353135a8f 100644
--- a/docs/rules/prefer-promise-reject-errors.md
+++ b/docs/rules/prefer-promise-reject-errors.md
@@ -65,9 +65,9 @@ new Promise(function(resolve, reject) {
 
 ## Known Limitations
 
-Due to the limits of static analysis, this rule cannot guarantee that you will only reject Promises with `Error` objects. While the rule will report cases where it can guarantee that the rejection reason is clearly not an `Error`, it will not report cases where there is uncertainty about whether a given reason is an `Error`. For more information on this caveat, see the [similar limitations](http://eslint.org/docs/rules/no-throw-literal#known-limitations) in the `no-throw-literal` rule.
+Due to the limits of static analysis, this rule cannot guarantee that you will only reject Promises with `Error` objects. While the rule will report cases where it can guarantee that the rejection reason is clearly not an `Error`, it will not report cases where there is uncertainty about whether a given reason is an `Error`. For more information on this caveat, see the [similar limitations](https://eslint.org/docs/rules/no-throw-literal#known-limitations) in the `no-throw-literal` rule.
 
-To avoid conflicts between rules, this rule does not report non-error values used in `throw` statements in async functions, even though these lead to Promise rejections. To lint for these cases, use the [`no-throw-literal`](http://eslint.org/docs/rules/no-throw-literal) rule.
+To avoid conflicts between rules, this rule does not report non-error values used in `throw` statements in async functions, even though these lead to Promise rejections. To lint for these cases, use the [`no-throw-literal`](https://eslint.org/docs/rules/no-throw-literal) rule.
 
 ## When Not To Use It
 
@@ -75,5 +75,5 @@ If you're using custom non-error values as Promise rejection reasons, you can tu
 
 ## Further Reading
 
-* [`no-throw-literal`](http://eslint.org/docs/rules/no-throw-literal)
+* [`no-throw-literal`](https://eslint.org/docs/rules/no-throw-literal)
 * [Warning: a promise was rejected with a non-error](http://bluebirdjs.com/docs/warning-explanations.html#warning-a-promise-was-rejected-with-a-non-error)
diff --git a/docs/rules/rest-spread-spacing.md b/docs/rules/rest-spread-spacing.md
index 6ff212770..bfc0d07c8 100644
--- a/docs/rules/rest-spread-spacing.md
+++ b/docs/rules/rest-spread-spacing.md
@@ -54,7 +54,7 @@ This rule aims to enforce consistent spacing between rest and spread operators a
 }
 ```
 
-Please read the user guide's section on [configuring parser options](http://eslint.org/docs/user-guide/configuring#specifying-parser-options) to learn more.
+Please read the user guide's section on [configuring parser options](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) to learn more.
 
 ## Options
 
diff --git a/docs/rules/sort-imports.md b/docs/rules/sort-imports.md
index c7c56e3aa..9d610f48f 100644
--- a/docs/rules/sort-imports.md
+++ b/docs/rules/sort-imports.md
@@ -203,5 +203,5 @@ This rule is a formatting preference and not following it won't negatively affec
 
 ## Related Rules
 
-* [sort-keys](http://eslint.org/docs/rules/sort-keys)
-* [sort-vars](http://eslint.org/docs/rules/sort-vars)
+* [sort-keys](https://eslint.org/docs/rules/sort-keys)
+* [sort-vars](https://eslint.org/docs/rules/sort-vars)
diff --git a/docs/rules/sort-keys.md b/docs/rules/sort-keys.md
index e4ddfece1..1960b4f75 100644
--- a/docs/rules/sort-keys.md
+++ b/docs/rules/sort-keys.md
@@ -170,8 +170,8 @@ If you don't want to notify about properties' order, then it's safe to disable t
 
 ## Related Rules
 
-* [sort-imports](http://eslint.org/docs/rules/sort-imports)
-* [sort-vars](http://eslint.org/docs/rules/sort-vars)
+* [sort-imports](https://eslint.org/docs/rules/sort-imports)
+* [sort-vars](https://eslint.org/docs/rules/sort-vars)
 
 ## Compatibility
 
diff --git a/docs/rules/sort-vars.md b/docs/rules/sort-vars.md
index 01b4d4e44..59600873c 100644
--- a/docs/rules/sort-vars.md
+++ b/docs/rules/sort-vars.md
@@ -74,5 +74,5 @@ This rule is a formatting preference and not following it won't negatively affec
 
 ## Related Rules
 
-* [sort-keys](http://eslint.org/docs/rules/sort-keys)
-* [sort-imports](http://eslint.org/docs/rules/sort-imports)
+* [sort-keys](https://eslint.org/docs/rules/sort-keys)
+* [sort-imports](https://eslint.org/docs/rules/sort-imports)
diff --git a/docs/rules/strict.md b/docs/rules/strict.md
index ee28bd9b0..e1cc4b7c6 100644
--- a/docs/rules/strict.md
+++ b/docs/rules/strict.md
@@ -269,4 +269,4 @@ function foo() {
 
 ## When Not To Use It
 
-In a codebase that has both strict and non-strict code, either turn this rule off, or [selectively disable it](http://eslint.org/docs/user-guide/configuring) where necessary. For example, functions referencing `arguments.callee` are invalid in strict mode. A [full list of strict mode differences](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode#Differences_from_non-strict_to_strict) is available on MDN.
+In a codebase that has both strict and non-strict code, either turn this rule off, or [selectively disable it](https://eslint.org/docs/user-guide/configuring) where necessary. For example, functions referencing `arguments.callee` are invalid in strict mode. A [full list of strict mode differences](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode#Differences_from_non-strict_to_strict) is available on MDN.
diff --git a/docs/user-guide/command-line-interface.md b/docs/user-guide/command-line-interface.md
index fb0152967..a42c54978 100644
--- a/docs/user-guide/command-line-interface.md
+++ b/docs/user-guide/command-line-interface.md
@@ -406,4 +406,4 @@ ESLint supports `.eslintignore` files to exclude files from the linting process
     node_modules/*
     **/vendor/*.js
 
-A more detailed breakdown of supported patterns and directories ESLint ignores by default can be found in [Configuring ESLint](http://eslint.org/docs/user-guide/configuring#ignoring-files-and-directories).
+A more detailed breakdown of supported patterns and directories ESLint ignores by default can be found in [Configuring ESLint](https://eslint.org/docs/user-guide/configuring#ignoring-files-and-directories).
diff --git a/docs/user-guide/getting-started.md b/docs/user-guide/getting-started.md
index 0e5673d25..52513bb84 100644
--- a/docs/user-guide/getting-started.md
+++ b/docs/user-guide/getting-started.md
@@ -63,7 +63,7 @@ Any plugins or shareable configs that you use must also be installed globally to
 
 ## Configuration
 
-**Note:** If you are coming from a version before 1.0.0 please see the [migration guide](http://eslint.org/docs/user-guide/migrating-to-1.0.0).
+**Note:** If you are coming from a version before 1.0.0 please see the [migration guide](https://eslint.org/docs/user-guide/migrating-to-1.0.0).
 
 After running `eslint --init`, you'll have a `.eslintrc` file in your directory. In it, you'll see some rules configured like this:
 
@@ -76,13 +76,13 @@ After running `eslint --init`, you'll have a `.eslintrc` file in your directory.
 }
 ```
 
-The names `"semi"` and `"quotes"` are the names of [rules](http://eslint.org/docs/rules) in ESLint. The first value is the error level of the rule and can be one of these values:
+The names `"semi"` and `"quotes"` are the names of [rules](https://eslint.org/docs/rules) in ESLint. The first value is the error level of the rule and can be one of these values:
 
 * `"off"` or `0` - turn the rule off
 * `"warn"` or `1` - turn the rule on as a warning (doesn't affect exit code)
 * `"error"` or `2` - turn the rule on as an error (exit code will be 1)
 
-The three error levels allow you fine-grained control over how ESLint applies rules (for more configuration options and details, see the [configuration docs](http://eslint.org/docs/user-guide/configuring)).
+The three error levels allow you fine-grained control over how ESLint applies rules (for more configuration options and details, see the [configuration docs](https://eslint.org/docs/user-guide/configuring)).
 
 Your `.eslintrc` configuration file will also include the line:
 
@@ -90,14 +90,14 @@ Your `.eslintrc` configuration file will also include the line:
     "extends": "eslint:recommended"
 ```
 
-Because of this line, all of the rules marked "(recommended)" on the [rules page](http://eslint.org/docs/rules) will be turned on.  Alternatively, you can use configurations that others have created by searching for "eslint-config" on [npmjs.com](https://www.npmjs.com/search?q=eslint-config).  ESLint will not lint your code unless you extend from a shared configuration or explicitly turn rules on in your configuration.
+Because of this line, all of the rules marked "(recommended)" on the [rules page](https://eslint.org/docs/rules) will be turned on.  Alternatively, you can use configurations that others have created by searching for "eslint-config" on [npmjs.com](https://www.npmjs.com/search?q=eslint-config).  ESLint will not lint your code unless you extend from a shared configuration or explicitly turn rules on in your configuration.
 
 ---
 
 ## Next Steps
 
-* Learn about [advanced configuration](http://eslint.org/docs/user-guide/configuring) of ESLint.
+* Learn about [advanced configuration](https://eslint.org/docs/user-guide/configuring) of ESLint.
 * Get familiar with the [command line options](/docs/user-guide/command-line-interface).
-* Explore [ESLint integrations](http://eslint.org/docs/user-guide/integrations) into other tools like editors, build systems, and more.
-* Can't find just the right rule?  Make your own [custom rule](http://eslint.org/docs/developer-guide/working-with-rules).
-* Make ESLint even better by [contributing](http://eslint.org/docs/developer-guide/contributing).
+* Explore [ESLint integrations](https://eslint.org/docs/user-guide/integrations) into other tools like editors, build systems, and more.
+* Can't find just the right rule?  Make your own [custom rule](https://eslint.org/docs/developer-guide/working-with-rules).
+* Make ESLint even better by [contributing](https://eslint.org/docs/developer-guide/contributing).
diff --git a/docs/user-guide/migrating-from-jscs.md b/docs/user-guide/migrating-from-jscs.md
index 12a68237c..7772fcd58 100644
--- a/docs/user-guide/migrating-from-jscs.md
+++ b/docs/user-guide/migrating-from-jscs.md
@@ -1,13 +1,13 @@
 # Migrating from JSCS
 
-In April 2016, we [announced](http://eslint.org/blog/2016/04/welcoming-jscs-to-eslint) that the JSCS project was shutting down and the JSCS team would be joining the ESLint team. This guide is intended to help those who are using JSCS to migrate their settings and projects to use ESLint. We've tried to automate as much of the conversion as possible, but there are some manual changes that are needed.
+In April 2016, we [announced](https://eslint.org/blog/2016/04/welcoming-jscs-to-eslint) that the JSCS project was shutting down and the JSCS team would be joining the ESLint team. This guide is intended to help those who are using JSCS to migrate their settings and projects to use ESLint. We've tried to automate as much of the conversion as possible, but there are some manual changes that are needed.
 
 ## Terminology
 
 Before beginning the process of migrating to ESLint, it's helpful to understand some of the terminology that ESLint uses and how it relates to terminology that JSCS uses.
 
 * **Configuration File** - In JSCS, the configuration file is `.jscsrc`, `.jscsrc.json`, `.jscsrc.yaml`, or `.jscsrs.js`. In ESLint, the configuration file can be `.eslintrc.json`, `.eslintrc.yml`, `.eslintrc.yaml`, or `.eslintrc.js` (there is also a deprecated `.eslintrc` file format).
-* **Presets** - In JSCS, there were numerous predefined configurations shipped directly within JSCS. ESLint ships with just one predefined configuration (`eslint:recommended`) that has no style rules enabled. However, ESLint does support [shareable configs](http://eslint.org/docs/developer-guide/shareable-configs). Shareable configs are configurations that are published on their own to npm and there are shareable configs available for almost all of the JSCS presets (see the "Converting Presets" section below). Additionally, the "preset" option in a configuration file is the equivalent of the ESLint "extends" option.
+* **Presets** - In JSCS, there were numerous predefined configurations shipped directly within JSCS. ESLint ships with just one predefined configuration (`eslint:recommended`) that has no style rules enabled. However, ESLint does support [shareable configs](https://eslint.org/docs/developer-guide/shareable-configs). Shareable configs are configurations that are published on their own to npm and there are shareable configs available for almost all of the JSCS presets (see the "Converting Presets" section below). Additionally, the "preset" option in a configuration file is the equivalent of the ESLint "extends" option.
 
 ## Convert Configuration Files Using Polyjuice
 
diff --git a/docs/user-guide/migrating-to-1.0.0.md b/docs/user-guide/migrating-to-1.0.0.md
index 47fdf2a82..637e3059e 100644
--- a/docs/user-guide/migrating-to-1.0.0.md
+++ b/docs/user-guide/migrating-to-1.0.0.md
@@ -20,62 +20,62 @@ This setting mimics some of the default behavior from 0.x, but not all. If you d
 
 The `"eslint:recommended"` configuration contains many of the same default rule settings from 0.x, but not all. These rules are no longer on by default, so you should review your settings to ensure they are still as you expect:
 
-* [no-alert](http://eslint.org/docs/rules/no-alert)
-* [no-array-constructor](http://eslint.org/docs/rules/no-array-constructor)
-* [no-caller](http://eslint.org/docs/rules/no-caller)
-* [no-catch-shadow](http://eslint.org/docs/rules/no-catch-shadow)
-* [no-empty-label](http://eslint.org/docs/rules/no-empty-label)
-* [no-eval](http://eslint.org/docs/rules/no-eval)
-* [no-extend-native](http://eslint.org/docs/rules/no-extend-native)
-* [no-extra-bind](http://eslint.org/docs/rules/no-extra-bind)
-* [no-extra-strict](http://eslint.org/docs/rules/no-extra-strict)
-* [no-implied-eval](http://eslint.org/docs/rules/no-implied-eval)
-* [no-iterator](http://eslint.org/docs/rules/no-iterator)
-* [no-label-var](http://eslint.org/docs/rules/no-label-var)
-* [no-labels](http://eslint.org/docs/rules/no-labels)
-* [no-lone-blocks](http://eslint.org/docs/rules/no-lone-blocks)
-* [no-loop-func](http://eslint.org/docs/rules/no-loop-func)
-* [no-multi-spaces](http://eslint.org/docs/rules/no-multi-spaces)
-* [no-multi-str](http://eslint.org/docs/rules/no-multi-str)
-* [no-native-reassign](http://eslint.org/docs/rules/no-native-reassign)
-* [no-new](http://eslint.org/docs/rules/no-new)
-* [no-new-func](http://eslint.org/docs/rules/no-new-func)
-* [no-new-object](http://eslint.org/docs/rules/no-new-object)
-* [no-new-wrappers](http://eslint.org/docs/rules/no-new-wrappers)
-* [no-octal-escape](http://eslint.org/docs/rules/no-octal-escape)
-* [no-process-exit](http://eslint.org/docs/rules/no-process-exit)
-* [no-proto](http://eslint.org/docs/rules/no-proto)
-* [no-return-assign](http://eslint.org/docs/rules/no-return-assign)
-* [no-script-url](http://eslint.org/docs/rules/no-script-url)
-* [no-sequences](http://eslint.org/docs/rules/no-sequences)
-* [no-shadow](http://eslint.org/docs/rules/no-shadow)
-* [no-shadow-restricted-names](http://eslint.org/docs/rules/no-shadow-restricted-names)
-* [no-spaced-func](http://eslint.org/docs/rules/no-spaced-func)
-* [no-trailing-spaces](http://eslint.org/docs/rules/no-trailing-spaces)
-* [no-undef-init](http://eslint.org/docs/rules/no-undef-init)
-* [no-underscore-dangle](http://eslint.org/docs/rules/no-underscore-dangle)
-* [no-unused-expressions](http://eslint.org/docs/rules/no-unused-expressions)
-* [no-use-before-define](http://eslint.org/docs/rules/no-use-before-define)
-* [no-with](http://eslint.org/docs/rules/no-with)
-* [no-wrap-func](http://eslint.org/docs/rules/no-wrap-func)
-* [camelcase](http://eslint.org/docs/rules/camelcase)
-* [comma-spacing](http://eslint.org/docs/rules/comma-spacing)
-* [consistent-return](http://eslint.org/docs/rules/consistent-return)
-* [curly](http://eslint.org/docs/rules/curly)
-* [dot-notation](http://eslint.org/docs/rules/dot-notation)
-* [eol-last](http://eslint.org/docs/rules/eol-last)
-* [eqeqeq](http://eslint.org/docs/rules/eqeqeq)
-* [key-spacing](http://eslint.org/docs/rules/key-spacing)
-* [new-cap](http://eslint.org/docs/rules/new-cap)
-* [new-parens](http://eslint.org/docs/rules/new-parens)
-* [quotes](http://eslint.org/docs/rules/quotes)
-* [semi](http://eslint.org/docs/rules/semi)
-* [semi-spacing](http://eslint.org/docs/rules/semi-spacing)
-* [space-infix-ops](http://eslint.org/docs/rules/space-infix-ops)
-* [space-return-throw-case](http://eslint.org/docs/rules/space-return-throw-case)
-* [space-unary-ops](http://eslint.org/docs/rules/space-unary-ops)
-* [strict](http://eslint.org/docs/rules/strict)
-* [yoda](http://eslint.org/docs/rules/yoda)
+* [no-alert](https://eslint.org/docs/rules/no-alert)
+* [no-array-constructor](https://eslint.org/docs/rules/no-array-constructor)
+* [no-caller](https://eslint.org/docs/rules/no-caller)
+* [no-catch-shadow](https://eslint.org/docs/rules/no-catch-shadow)
+* [no-empty-label](https://eslint.org/docs/rules/no-empty-label)
+* [no-eval](https://eslint.org/docs/rules/no-eval)
+* [no-extend-native](https://eslint.org/docs/rules/no-extend-native)
+* [no-extra-bind](https://eslint.org/docs/rules/no-extra-bind)
+* [no-extra-strict](https://eslint.org/docs/rules/no-extra-strict)
+* [no-implied-eval](https://eslint.org/docs/rules/no-implied-eval)
+* [no-iterator](https://eslint.org/docs/rules/no-iterator)
+* [no-label-var](https://eslint.org/docs/rules/no-label-var)
+* [no-labels](https://eslint.org/docs/rules/no-labels)
+* [no-lone-blocks](https://eslint.org/docs/rules/no-lone-blocks)
+* [no-loop-func](https://eslint.org/docs/rules/no-loop-func)
+* [no-multi-spaces](https://eslint.org/docs/rules/no-multi-spaces)
+* [no-multi-str](https://eslint.org/docs/rules/no-multi-str)
+* [no-native-reassign](https://eslint.org/docs/rules/no-native-reassign)
+* [no-new](https://eslint.org/docs/rules/no-new)
+* [no-new-func](https://eslint.org/docs/rules/no-new-func)
+* [no-new-object](https://eslint.org/docs/rules/no-new-object)
+* [no-new-wrappers](https://eslint.org/docs/rules/no-new-wrappers)
+* [no-octal-escape](https://eslint.org/docs/rules/no-octal-escape)
+* [no-process-exit](https://eslint.org/docs/rules/no-process-exit)
+* [no-proto](https://eslint.org/docs/rules/no-proto)
+* [no-return-assign](https://eslint.org/docs/rules/no-return-assign)
+* [no-script-url](https://eslint.org/docs/rules/no-script-url)
+* [no-sequences](https://eslint.org/docs/rules/no-sequences)
+* [no-shadow](https://eslint.org/docs/rules/no-shadow)
+* [no-shadow-restricted-names](https://eslint.org/docs/rules/no-shadow-restricted-names)
+* [no-spaced-func](https://eslint.org/docs/rules/no-spaced-func)
+* [no-trailing-spaces](https://eslint.org/docs/rules/no-trailing-spaces)
+* [no-undef-init](https://eslint.org/docs/rules/no-undef-init)
+* [no-underscore-dangle](https://eslint.org/docs/rules/no-underscore-dangle)
+* [no-unused-expressions](https://eslint.org/docs/rules/no-unused-expressions)
+* [no-use-before-define](https://eslint.org/docs/rules/no-use-before-define)
+* [no-with](https://eslint.org/docs/rules/no-with)
+* [no-wrap-func](https://eslint.org/docs/rules/no-wrap-func)
+* [camelcase](https://eslint.org/docs/rules/camelcase)
+* [comma-spacing](https://eslint.org/docs/rules/comma-spacing)
+* [consistent-return](https://eslint.org/docs/rules/consistent-return)
+* [curly](https://eslint.org/docs/rules/curly)
+* [dot-notation](https://eslint.org/docs/rules/dot-notation)
+* [eol-last](https://eslint.org/docs/rules/eol-last)
+* [eqeqeq](https://eslint.org/docs/rules/eqeqeq)
+* [key-spacing](https://eslint.org/docs/rules/key-spacing)
+* [new-cap](https://eslint.org/docs/rules/new-cap)
+* [new-parens](https://eslint.org/docs/rules/new-parens)
+* [quotes](https://eslint.org/docs/rules/quotes)
+* [semi](https://eslint.org/docs/rules/semi)
+* [semi-spacing](https://eslint.org/docs/rules/semi-spacing)
+* [space-infix-ops](https://eslint.org/docs/rules/space-infix-ops)
+* [space-return-throw-case](https://eslint.org/docs/rules/space-return-throw-case)
+* [space-unary-ops](https://eslint.org/docs/rules/space-unary-ops)
+* [strict](https://eslint.org/docs/rules/strict)
+* [yoda](https://eslint.org/docs/rules/yoda)
 
 See also: the [full diff](https://github.com/eslint/eslint/commit/e3e9dbd9876daf4bdeb4e15f8a76a9d5e6e03e39#diff-b01a5cfd9361ca9280a460fd6bb8edbbL1) where the defaults were changed.
 
@@ -148,19 +148,19 @@ Here's a configuration file with the closest equivalent of the old defaults:
 
 Over the past several releases, we have been deprecating rules and introducing new rules to take their place. The following is a list of the removed rules and their replacements:
 
-* [generator-star](http://eslint.org/docs/rules/generator-star) is replaced by [generator-star-spacing](http://eslint.org/docs/rules/generator-star-spacing)
-* [global-strict](http://eslint.org/docs/rules/global-strict) is replaced by [strict](http://eslint.org/docs/rules/strict)
-* [no-comma-dangle](http://eslint.org/docs/rules/no-comma-dangle) is replaced by [comma-dangle](http://eslint.org/docs/rules/comma-dangle)
-* [no-empty-class](http://eslint.org/docs/rules/no-empty-class) is replaced by [no-empty-character-class](http://eslint.org/docs/rules/no-empty-character-class)
-* [no-extra-strict](http://eslint.org/docs/rules/no-extra-strict) is replaced by [strict](http://eslint.org/docs/rules/strict)
-* [no-reserved-keys](http://eslint.org/docs/rules/no-reserved-keys) is replaced by [quote-props](http://eslint.org/docs/rules/quote-props)
-* [no-space-before-semi](http://eslint.org/docs/rules/no-space-before-semi) is replaced by [semi-spacing](http://eslint.org/docs/rules/semi-spacing)
-* [no-wrap-func](http://eslint.org/docs/rules/no-wrap-func) is replaced by [no-extra-parens](http://eslint.org/docs/rules/no-extra-parens)
-* [space-after-function-name](http://eslint.org/docs/rules/space-after-function-name) is replaced by [space-before-function-paren](http://eslint.org/docs/rules/space-before-function-paren)
-* [space-before-function-parentheses](http://eslint.org/docs/rules/space-before-function-parentheses) is replaced by [space-before-function-paren](http://eslint.org/docs/rules/space-before-function-paren)
-* [space-in-brackets](http://eslint.org/docs/rules/space-in-brackets) is replaced by[object-curly-spacing](http://eslint.org/docs/rules/object-curly-spacing) and [array-bracket-spacing](http://eslint.org/docs/rules/array-bracket-spacing)
-* [space-unary-word-ops](http://eslint.org/docs/rules/space-unary-word-ops) is replaced by [space-unary-ops](http://eslint.org/docs/rules/space-unary-ops)
-* [spaced-line-comment](http://eslint.org/docs/rules/spaced-line-comment) is replaced by [spaced-comment](http://eslint.org/docs/rules/spaced-comment)
+* [generator-star](https://eslint.org/docs/rules/generator-star) is replaced by [generator-star-spacing](https://eslint.org/docs/rules/generator-star-spacing)
+* [global-strict](https://eslint.org/docs/rules/global-strict) is replaced by [strict](https://eslint.org/docs/rules/strict)
+* [no-comma-dangle](https://eslint.org/docs/rules/no-comma-dangle) is replaced by [comma-dangle](https://eslint.org/docs/rules/comma-dangle)
+* [no-empty-class](https://eslint.org/docs/rules/no-empty-class) is replaced by [no-empty-character-class](https://eslint.org/docs/rules/no-empty-character-class)
+* [no-extra-strict](https://eslint.org/docs/rules/no-extra-strict) is replaced by [strict](https://eslint.org/docs/rules/strict)
+* [no-reserved-keys](https://eslint.org/docs/rules/no-reserved-keys) is replaced by [quote-props](https://eslint.org/docs/rules/quote-props)
+* [no-space-before-semi](https://eslint.org/docs/rules/no-space-before-semi) is replaced by [semi-spacing](https://eslint.org/docs/rules/semi-spacing)
+* [no-wrap-func](https://eslint.org/docs/rules/no-wrap-func) is replaced by [no-extra-parens](https://eslint.org/docs/rules/no-extra-parens)
+* [space-after-function-name](https://eslint.org/docs/rules/space-after-function-name) is replaced by [space-before-function-paren](https://eslint.org/docs/rules/space-before-function-paren)
+* [space-before-function-parentheses](https://eslint.org/docs/rules/space-before-function-parentheses) is replaced by [space-before-function-paren](https://eslint.org/docs/rules/space-before-function-paren)
+* [space-in-brackets](https://eslint.org/docs/rules/space-in-brackets) is replaced by[object-curly-spacing](https://eslint.org/docs/rules/object-curly-spacing) and [array-bracket-spacing](https://eslint.org/docs/rules/array-bracket-spacing)
+* [space-unary-word-ops](https://eslint.org/docs/rules/space-unary-word-ops) is replaced by [space-unary-ops](https://eslint.org/docs/rules/space-unary-ops)
+* [spaced-line-comment](https://eslint.org/docs/rules/spaced-line-comment) is replaced by [spaced-comment](https://eslint.org/docs/rules/spaced-comment)
 
 **To address:** You'll need to update your rule configurations to use the new rules. ESLint v1.0.0 will also warn you when you're using a rule that has been removed and will suggest the replacement rules. Hopefully, this will result in few surprises during the upgrade process.
 
diff --git a/docs/user-guide/migrating-to-2.0.0.md b/docs/user-guide/migrating-to-2.0.0.md
index 2f4ccda66..5b2c541e0 100644
--- a/docs/user-guide/migrating-to-2.0.0.md
+++ b/docs/user-guide/migrating-to-2.0.0.md
@@ -51,11 +51,11 @@ module.exports = {
 
 The following rules have been deprecated with new rules created to take their place. The following is a list of the removed rules and their replacements:
 
-* [no-arrow-condition](http://eslint.org/docs/rules/no-arrow-condition) is replaced by a combination of [no-confusing-arrow](http://eslint.org/docs/rules/no-confusing-arrow) and [no-constant-condition](http://eslint.org/docs/rules/no-constant-condition). Turn on both of these rules to get the same functionality as `no-arrow-condition`.
-* [no-empty-label](http://eslint.org/docs/rules/no-empty-label) is replaced by [no-labels](http://eslint.org/docs/rules/no-labels) with `{"allowLoop": true, "allowSwitch": true}` option.
-* [space-after-keywords](http://eslint.org/docs/rules/space-after-keywords) is replaced by [keyword-spacing](http://eslint.org/docs/rules/keyword-spacing).
-* [space-before-keywords](http://eslint.org/docs/rules/space-before-keywords) is replaced by [keyword-spacing](http://eslint.org/docs/rules/keyword-spacing).
-* [space-return-throw-case](http://eslint.org/docs/rules/space-return-throw-case) is replaced by [keyword-spacing](http://eslint.org/docs/rules/keyword-spacing).
+* [no-arrow-condition](https://eslint.org/docs/rules/no-arrow-condition) is replaced by a combination of [no-confusing-arrow](https://eslint.org/docs/rules/no-confusing-arrow) and [no-constant-condition](https://eslint.org/docs/rules/no-constant-condition). Turn on both of these rules to get the same functionality as `no-arrow-condition`.
+* [no-empty-label](https://eslint.org/docs/rules/no-empty-label) is replaced by [no-labels](https://eslint.org/docs/rules/no-labels) with `{"allowLoop": true, "allowSwitch": true}` option.
+* [space-after-keywords](https://eslint.org/docs/rules/space-after-keywords) is replaced by [keyword-spacing](https://eslint.org/docs/rules/keyword-spacing).
+* [space-before-keywords](https://eslint.org/docs/rules/space-before-keywords) is replaced by [keyword-spacing](https://eslint.org/docs/rules/keyword-spacing).
+* [space-return-throw-case](https://eslint.org/docs/rules/space-return-throw-case) is replaced by [keyword-spacing](https://eslint.org/docs/rules/keyword-spacing).
 
 **To address:** You'll need to update your rule configurations to use the new rules. ESLint v2.0.0 will also warn you when you're using a rule that has been removed and will suggest the replacement rules. Hopefully, this will result in few surprises during the upgrade process.
 
@@ -207,17 +207,17 @@ If you're not using `ecmaFeatures` in your configuration or your custom/plugin r
 
 In 2.0.0, the following 11 rules were added to `"eslint:recommended"`.
 
-* [constructor-super](http://eslint.org/docs/rules/constructor-super)
-* [no-case-declarations](http://eslint.org/docs/rules/no-case-declarations)
-* [no-class-assign](http://eslint.org/docs/rules/no-class-assign)
-* [no-const-assign](http://eslint.org/docs/rules/no-const-assign)
-* [no-dupe-class-members](http://eslint.org/docs/rules/no-dupe-class-members)
-* [no-empty-pattern](http://eslint.org/docs/rules/no-empty-pattern)
-* [no-new-symbol](http://eslint.org/docs/rules/no-new-symbol)
-* [no-self-assign](http://eslint.org/docs/rules/no-self-assign)
-* [no-this-before-super](http://eslint.org/docs/rules/no-this-before-super)
-* [no-unexpected-multiline](http://eslint.org/docs/rules/no-unexpected-multiline)
-* [no-unused-labels](http://eslint.org/docs/rules/no-unused-labels)
+* [constructor-super](https://eslint.org/docs/rules/constructor-super)
+* [no-case-declarations](https://eslint.org/docs/rules/no-case-declarations)
+* [no-class-assign](https://eslint.org/docs/rules/no-class-assign)
+* [no-const-assign](https://eslint.org/docs/rules/no-const-assign)
+* [no-dupe-class-members](https://eslint.org/docs/rules/no-dupe-class-members)
+* [no-empty-pattern](https://eslint.org/docs/rules/no-empty-pattern)
+* [no-new-symbol](https://eslint.org/docs/rules/no-new-symbol)
+* [no-self-assign](https://eslint.org/docs/rules/no-self-assign)
+* [no-this-before-super](https://eslint.org/docs/rules/no-this-before-super)
+* [no-unexpected-multiline](https://eslint.org/docs/rules/no-unexpected-multiline)
+* [no-unused-labels](https://eslint.org/docs/rules/no-unused-labels)
 
 **To address:** If you don't want to be notified by those rules, you can simply disable those rules.
 
diff --git a/docs/user-guide/migrating-to-3.0.0.md b/docs/user-guide/migrating-to-3.0.0.md
index 510527712..3326087c0 100644
--- a/docs/user-guide/migrating-to-3.0.0.md
+++ b/docs/user-guide/migrating-to-3.0.0.md
@@ -35,17 +35,17 @@ To create a new configuration, use `eslint --init`.
 
 In 3.0.0, the following rules were added to `"eslint:recommended"`:
 
-* [`no-unsafe-finally`](http://eslint.org/docs/rules/no-unsafe-finally) helps catch `finally` clauses that may not behave as you think.
-* [`no-native-reassign`](http://eslint.org/docs/rules/no-native-reassign) was previously part of `no-undef`, but was split out because it didn't make sense as part of another rule. The `no-native-reassign` rule warns whenever you try to overwrite a read-only global variable.
-* [`require-yield`](http://eslint.org/docs/rules/require-yield) helps to identify generator functions that do not have the `yield` keyword.
+* [`no-unsafe-finally`](https://eslint.org/docs/rules/no-unsafe-finally) helps catch `finally` clauses that may not behave as you think.
+* [`no-native-reassign`](https://eslint.org/docs/rules/no-native-reassign) was previously part of `no-undef`, but was split out because it didn't make sense as part of another rule. The `no-native-reassign` rule warns whenever you try to overwrite a read-only global variable.
+* [`require-yield`](https://eslint.org/docs/rules/require-yield) helps to identify generator functions that do not have the `yield` keyword.
 
 The following rules were removed from `"eslint:recommended"`:
 
-* [`comma-dangle`](http://eslint.org/docs/rules/comma-dangle) used to be recommended because Internet Explorer 8 and earlier threw a syntax error when it found a dangling comma on object literal properties. However, [Internet Explorer 8 was end-of-lifed](https://www.microsoft.com/en-us/WindowsForBusiness/End-of-IE-support) in January 2016 and all other active browsers allow dangling commas. As such, we consider dangling commas to now be a stylistic issue instead of a possible error.
+* [`comma-dangle`](https://eslint.org/docs/rules/comma-dangle) used to be recommended because Internet Explorer 8 and earlier threw a syntax error when it found a dangling comma on object literal properties. However, [Internet Explorer 8 was end-of-lifed](https://www.microsoft.com/en-us/WindowsForBusiness/End-of-IE-support) in January 2016 and all other active browsers allow dangling commas. As such, we consider dangling commas to now be a stylistic issue instead of a possible error.
 
 The following rules were modified:
 
-* [`complexity`](http://eslint.org/docs/rules/complexity) used to have a hardcoded default of 11 in `eslint:recommended` that would be used if you turned the rule on without specifying a maximum. The default is now 20. The rule actually always had a default of 20, but `eslint:recommended` was overriding it by mistake.
+* [`complexity`](https://eslint.org/docs/rules/complexity) used to have a hardcoded default of 11 in `eslint:recommended` that would be used if you turned the rule on without specifying a maximum. The default is now 20. The rule actually always had a default of 20, but `eslint:recommended` was overriding it by mistake.
 
 **To address:** If you want to mimic how `eslint:recommended` worked in v2.x, you can use the following:
 
diff --git a/docs/user-guide/migrating-to-4.0.0.md b/docs/user-guide/migrating-to-4.0.0.md
index 8d02b5420..3a0aa9fd2 100644
--- a/docs/user-guide/migrating-to-4.0.0.md
+++ b/docs/user-guide/migrating-to-4.0.0.md
@@ -32,7 +32,7 @@ The lists below are ordered roughly by the number of users each change is expect
 
 ## <a name="eslint-recommended-changes"/> `eslint:recommended` changes
 
-Two new rules have been added to the [`eslint:recommended`](http://eslint.org/docs/user-guide/configuring#using-eslintrecommended) config:
+Two new rules have been added to the [`eslint:recommended`](https://eslint.org/docs/user-guide/configuring#using-eslintrecommended) config:
 
 * [`no-compare-neg-zero`](/docs/rules/no-compare-neg-zero) disallows comparisons to `-0`
 * [`no-useless-escape`](/docs/rules/no-useless-escape) disallows uselessly-escaped characters in strings and regular expressions
diff --git a/lib/formatters/html-template-message.html b/lib/formatters/html-template-message.html
index 068317274..66f49ff49 100644
--- a/lib/formatters/html-template-message.html
+++ b/lib/formatters/html-template-message.html
@@ -3,6 +3,6 @@
     <td class="clr-<%= severityNumber %>"><%= severityName %></td>
     <td><%- message %></td>
     <td>
-        <a href="http://eslint.org/docs/rules/<%= ruleId %>" target="_blank"><%= ruleId %></a>
+        <a href="https://eslint.org/docs/rules/<%= ruleId %>" target="_blank"><%= ruleId %></a>
     </td>
 </tr>
diff --git a/lib/linter.js b/lib/linter.js
index a8fa58b9d..8f1520aaf 100755
--- a/lib/linter.js
+++ b/lib/linter.js
@@ -9,8 +9,7 @@
 // Requirements
 //------------------------------------------------------------------------------
 
-const EventEmitter = require("events").EventEmitter,
-    eslintScope = require("eslint-scope"),
+const eslintScope = require("eslint-scope"),
     levn = require("levn"),
     lodash = require("lodash"),
     blankScriptAST = require("../conf/blank-script.json"),
@@ -20,6 +19,7 @@ const EventEmitter = require("events").EventEmitter,
     validator = require("./config/config-validator"),
     Environments = require("./config/environments"),
     applyDisableDirectives = require("./util/apply-disable-directives"),
+    createEmitter = require("./util/safe-emitter"),
     NodeEventGenerator = require("./util/node-event-generator"),
     SourceCode = require("./util/source-code"),
     Traverser = require("./util/traverser"),
@@ -817,7 +817,7 @@ module.exports = class Linter {
             disableDirectives = [];
         }
 
-        const emitter = new EventEmitter().setMaxListeners(Infinity);
+        const emitter = createEmitter();
         const traverser = new Traverser();
         const ecmaFeatures = config.parserOptions.ecmaFeatures || {};
         const ecmaVersion = config.parserOptions.ecmaVersion || 5;
@@ -860,7 +860,7 @@ module.exports = class Linter {
                      */
                     _linter: {
                         report() {},
-                        on: emitter.on.bind(emitter)
+                        on: emitter.on
                     }
                 }
             )
diff --git a/lib/util/node-event-generator.js b/lib/util/node-event-generator.js
index 568a3b7fe..05b343ae9 100644
--- a/lib/util/node-event-generator.js
+++ b/lib/util/node-event-generator.js
@@ -194,7 +194,7 @@ const parseSelector = lodash.memoize(rawSelector => {
  *
  * ```ts
  * interface EventGenerator {
- *     emitter: EventEmitter;
+ *     emitter: SafeEmitter;
  *     enterNode(node: ASTNode): void;
  *     leaveNode(node: ASTNode): void;
  * }
@@ -203,8 +203,10 @@ const parseSelector = lodash.memoize(rawSelector => {
 class NodeEventGenerator {
 
     /**
-    * @param {EventEmitter} emitter - An event emitter which is the destination of events. This emitter must already
+    * @param {SafeEmitter} emitter
+    * An SafeEmitter which is the destination of events. This emitter must already
     * have registered listeners for all of the events that it needs to listen for.
+    * (See lib/util/safe-emitter.js for more details on `SafeEmitter`.)
     * @returns {NodeEventGenerator} new instance
     */
     constructor(emitter) {
@@ -215,23 +217,7 @@ class NodeEventGenerator {
         this.anyTypeEnterSelectors = [];
         this.anyTypeExitSelectors = [];
 
-        const eventNames = typeof emitter.eventNames === "function"
-
-            // Use the built-in eventNames() function if available (Node 6+)
-            ? emitter.eventNames()
-
-            /*
-             * Otherwise, use the private _events property.
-             * Using a private property isn't ideal here, but this seems to
-             * be the best way to get a list of event names without overriding
-             * addEventListener, which would hurt performance. This property
-             * is widely used and unlikely to be removed in a future version
-             * (see https://github.com/nodejs/node/issues/1817). Also, future
-             * node versions will have eventNames() anyway.
-             */
-            : Object.keys(emitter._events); // eslint-disable-line no-underscore-dangle
-
-        eventNames.forEach(rawSelector => {
+        emitter.eventNames().forEach(rawSelector => {
             const selector = parseSelector(rawSelector);
 
             if (selector.listenerTypes) {
diff --git a/lib/util/safe-emitter.js b/lib/util/safe-emitter.js
new file mode 100644
index 000000000..242cbe429
--- /dev/null
+++ b/lib/util/safe-emitter.js
@@ -0,0 +1,54 @@
+/**
+ * @fileoverview A variant of EventEmitter which does not give listeners information about each other
+ * @author Teddy Katz
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Typedefs
+//------------------------------------------------------------------------------
+
+/**
+ * An object describing an AST selector
+ * @typedef {Object} SafeEmitter
+ * @property {function(eventName: string, listenerFunc: Function): void} on Adds a listener for a given event name
+ * @property {function(eventName: string, arg1?: any, arg2?: any, arg3?: any)} emit Emits an event with a given name.
+ * This calls all the listeners that were listening for that name, with `arg1`, `arg2`, and `arg3` as arguments.
+ * @property {function(): string[]} eventNames Gets the list of event names that have registered listeners.
+ */
+
+/**
+ * Creates an object which can listen for and emit events.
+ * This is similar to the EventEmitter API in Node's standard library, but it has a few differences.
+ * The goal is to allow multiple modules to attach arbitrary listeners to the same emitter, without
+ * letting the modules know about each other at all.
+ * 1. It has no special keys like `error` and `newListener`, which would allow modules to detect when
+ * another module throws an error or registers a listener.
+ * 2. It calls listener functions without any `this` value. (`EventEmitter` calls listeners with a
+ * `this` value of the emitter instance, which would give listeners access to other listeners.)
+ * 3. Events can be emitted with at most 3 arguments. (For example: when using `emitter.emit('foo', a, b, c)`,
+ * the arguments `a`, `b`, and `c` will be passed to the listener functions.)
+ * @returns {SafeEmitter} An emitter
+ */
+module.exports = () => {
+    const listeners = Object.create(null);
+
+    return Object.freeze({
+        on(eventName, listener) {
+            if (eventName in listeners) {
+                listeners[eventName].push(listener);
+            } else {
+                listeners[eventName] = [listener];
+            }
+        },
+        emit(eventName, a, b, c) {
+            if (eventName in listeners) {
+                listeners[eventName].forEach(listener => listener(a, b, c));
+            }
+        },
+        eventNames() {
+            return Object.keys(listeners);
+        }
+    });
+};
diff --git a/package.json b/package.json
index b7dd3a9ef..3e83513fc 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,7 @@
     "messages"
   ],
   "repository": "eslint/eslint",
-  "homepage": "http://eslint.org",
+  "homepage": "https://eslint.org",
   "bugs": "https://github.com/eslint/eslint/issues/",
   "dependencies": {
     "ajv": "^5.2.0",
diff --git a/packages/eslint-config-eslint/README.md b/packages/eslint-config-eslint/README.md
index f16805cd3..36635964d 100644
--- a/packages/eslint-config-eslint/README.md
+++ b/packages/eslint-config-eslint/README.md
@@ -3,7 +3,7 @@
 
 # ESLint Configuration
 
-[Website](http://eslint.org) | [Configuring](http://eslint.org/docs/user-guide/configuring) | [Rules](http://eslint.org/docs/rules/) | [Contributing](http://eslint.org/docs/developer-guide/contributing) | [Twitter](https://twitter.com/geteslint) | [Mailing List](https://groups.google.com/group/eslint)
+[Website](https://eslint.org) | [Configuring](https://eslint.org/docs/user-guide/configuring) | [Rules](https://eslint.org/docs/rules/) | [Contributing](https://eslint.org/docs/developer-guide/contributing) | [Twitter](https://twitter.com/geteslint) | [Mailing List](https://groups.google.com/group/eslint)
 
 Contains the default ESLint configuration for ESLint projects.
 
diff --git a/packages/eslint-config-eslint/package.json b/packages/eslint-config-eslint/package.json
index c36dda11b..9098c1e19 100644
--- a/packages/eslint-config-eslint/package.json
+++ b/packages/eslint-config-eslint/package.json
@@ -17,7 +17,7 @@
     "type": "git",
     "url": "https://github.com/eslint/eslint"
   },
-  "homepage": "http://eslint.org",
+  "homepage": "https://eslint.org",
   "bugs": "https://github.com/eslint/eslint/issues/",
   "dependencies": {
     "js-yaml": "^3.5.1"
diff --git a/templates/issue-create.md.ejs b/templates/issue-create.md.ejs
index f7641ebe9..71296ea5f 100644
--- a/templates/issue-create.md.ejs
+++ b/templates/issue-create.md.ejs
@@ -5,4 +5,4 @@
 3. The actual ESLint output complete with numbers
 4. What you expected to happen instead
 
-Requesting a new rule? Please see [Proposing a New Rule](http://eslint.org/docs/developer-guide/contributing/new-rules) for instructions.
+Requesting a new rule? Please see [Proposing a New Rule](https://eslint.org/docs/developer-guide/contributing/new-rules) for instructions.
diff --git a/templates/needs-info.md.ejs b/templates/needs-info.md.ejs
index 539e12da5..d1eb6d4a5 100644
--- a/templates/needs-info.md.ejs
+++ b/templates/needs-info.md.ejs
@@ -7,8 +7,8 @@ If you're reporting a bug, please be sure to include:
 3. The actual ESLint output complete with numbers
 4. What you expected to happen instead
 
-Requesting a new rule? Please see [Proposing a New Rule](http://eslint.org/docs/developer-guide/contributing/new-rules) for instructions.
+Requesting a new rule? Please see [Proposing a New Rule](https://eslint.org/docs/developer-guide/contributing/new-rules) for instructions.
 
-Requesting a rule change? Please see [Proposing a Rule Change](http://eslint.org/docs/developer-guide/contributing/rule-changes) for instructions.
+Requesting a rule change? Please see [Proposing a Rule Change](https://eslint.org/docs/developer-guide/contributing/rule-changes) for instructions.
 
 If it's something else, please just provide as much additional information as possible. Thanks!
diff --git a/templates/pr-create.md.ejs b/templates/pr-create.md.ejs
index 6c41600a4..1ff9e16b7 100644
--- a/templates/pr-create.md.ejs
+++ b/templates/pr-create.md.ejs
@@ -16,11 +16,11 @@ if (meta.commits) {
     var log = meta.commits[0].commit.message.split(/\r?\n/g)[0];
 
     if (!isValidCommitFlag(log)) {
-        problems.push("The commit summary needs to begin with a tag (such as `Fix:` or `Update:`). Please check out our [guide](http://eslint.org/docs/developer-guide/contributing/pull-requests#step-2-make-your-changes) for how to properly format your commit summary and [update](http://eslint.org/docs/developer-guide/contributing/pull-requests#updating-the-commit-message) it on this pull request.")
+        problems.push("The commit summary needs to begin with a tag (such as `Fix:` or `Update:`). Please check out our [guide](https://eslint.org/docs/developer-guide/contributing/pull-requests#step-2-make-your-changes) for how to properly format your commit summary and [update](https://eslint.org/docs/developer-guide/contributing/pull-requests#updating-the-commit-message) it on this pull request.")
     }
 
     if (log.length > 72) {
-        problems.push("The commit summary must be 72 characters or shorter. Please check out our [guide](http://eslint.org/docs/developer-guide/contributing/pull-requests#step-2-make-your-changes) for how to properly format your commit summary and [update](http://eslint.org/docs/developer-guide/contributing/pull-requests#updating-the-commit-message) it on this pull request.");
+        problems.push("The commit summary must be 72 characters or shorter. Please check out our [guide](https://eslint.org/docs/developer-guide/contributing/pull-requests#step-2-make-your-changes) for how to properly format your commit summary and [update](https://eslint.org/docs/developer-guide/contributing/pull-requests#updating-the-commit-message) it on this pull request.");
     }
 }
 
@@ -33,7 +33,7 @@ Thanks for the pull request, @<%= payload.sender.login %>! I took a look to make
 
 Can you please update the pull request to address these?
 
-(More information can be found in our [pull request guide](http://eslint.org/docs/developer-guide/contributing/pull-requests).)
+(More information can be found in our [pull request guide](https://eslint.org/docs/developer-guide/contributing/pull-requests).)
 <% } else { %>
 LGTM
 <% } %>


Test patch:
diff --git a/tests/lib/code-path-analysis/code-path-analyzer.js b/tests/lib/code-path-analysis/code-path-analyzer.js
index 82384b157..e9878d667 100644
--- a/tests/lib/code-path-analysis/code-path-analyzer.js
+++ b/tests/lib/code-path-analysis/code-path-analyzer.js
@@ -10,11 +10,11 @@
 //------------------------------------------------------------------------------
 
 const assert = require("assert"),
-    EventEmitter = require("events").EventEmitter,
     fs = require("fs"),
     path = require("path"),
     Linter = require("../../../lib/linter"),
     EventGeneratorTester = require("../../../tools/internal-testers/event-generator-tester"),
+    createEmitter = require("../../../lib/util/safe-emitter"),
     debug = require("../../../lib/code-path-analysis/debug-helpers"),
     CodePath = require("../../../lib/code-path-analysis/code-path"),
     CodePathAnalyzer = require("../../../lib/code-path-analysis/code-path-analyzer"),
@@ -55,7 +55,7 @@ function getExpectedDotArrows(source) {
 
 describe("CodePathAnalyzer", () => {
     EventGeneratorTester.testEventGeneratorInterface(
-        new CodePathAnalyzer(new NodeEventGenerator(new EventEmitter()))
+        new CodePathAnalyzer(new NodeEventGenerator(createEmitter()))
     );
 
     describe("interface of code paths", () => {
diff --git a/tests/lib/linter.js b/tests/lib/linter.js
index eda0bd571..a6352c0f9 100644
--- a/tests/lib/linter.js
+++ b/tests/lib/linter.js
@@ -100,6 +100,23 @@ describe("Linter", () => {
                 linter.verify(code, config, filename, true);
             }, "Intentional error.");
         });
+
+        it("does not call rule listeners with a `this` value", () => {
+            const spy = sandbox.spy();
+
+            linter.defineRule("checker", () => ({ Program: spy }));
+            linter.verify("foo", { rules: { checker: "error" } });
+            assert(spy.calledOnce);
+            assert.strictEqual(spy.firstCall.thisValue, void 0);
+        });
+
+        it("does not allow listeners to use special EventEmitter values", () => {
+            const spy = sandbox.spy();
+
+            linter.defineRule("checker", () => ({ newListener: spy }));
+            linter.verify("foo", { rules: { checker: "error", "no-undef": "error" } });
+            assert(spy.notCalled);
+        });
     });
 
     describe("context.getSourceLines()", () => {
diff --git a/tests/lib/util/node-event-generator.js b/tests/lib/util/node-event-generator.js
index b59fabce7..67b6fa53a 100644
--- a/tests/lib/util/node-event-generator.js
+++ b/tests/lib/util/node-event-generator.js
@@ -9,11 +9,11 @@
 //------------------------------------------------------------------------------
 
 const assert = require("assert"),
-    EventEmitter = require("events").EventEmitter,
     sinon = require("sinon"),
     espree = require("espree"),
     estraverse = require("estraverse"),
     EventGeneratorTester = require("../../../tools/internal-testers/event-generator-tester"),
+    createEmitter = require("../../../lib/util/safe-emitter"),
     NodeEventGenerator = require("../../../lib/util/node-event-generator");
 
 //------------------------------------------------------------------------------
@@ -30,16 +30,16 @@ const ESPREE_CONFIG = {
 
 describe("NodeEventGenerator", () => {
     EventGeneratorTester.testEventGeneratorInterface(
-        new NodeEventGenerator(new EventEmitter())
+        new NodeEventGenerator(createEmitter())
     );
 
     describe("entering a single AST node", () => {
         let emitter, generator;
 
         beforeEach(() => {
-            emitter = new EventEmitter();
+            emitter = Object.create(createEmitter(), { emit: { value: sinon.spy() } });
+
             ["Foo", "Bar", "Foo > Bar", "Foo:exit"].forEach(selector => emitter.on(selector, () => {}));
-            emitter.emit = sinon.spy(emitter.emit);
             generator = new NodeEventGenerator(emitter);
         });
 
@@ -82,13 +82,15 @@ describe("NodeEventGenerator", () => {
          */
         function getEmissions(ast, possibleQueries) {
             const emissions = [];
-            const emitter = new EventEmitter();
+            const emitter = Object.create(createEmitter(), {
+                emit: {
+                    value: (selector, node) => emissions.push([selector, node])
+                }
+            });
 
             possibleQueries.forEach(query => emitter.on(query, () => {}));
             const generator = new NodeEventGenerator(emitter);
 
-            emitter.emit = (selector, node) => emissions.push([selector, node]);
-
             estraverse.traverse(ast, {
                 enter(node, parent) {
                     node.parent = parent;
@@ -308,7 +310,7 @@ describe("NodeEventGenerator", () => {
 
     describe("parsing an invalid selector", () => {
         it("throws a useful error", () => {
-            const emitter = new EventEmitter();
+            const emitter = createEmitter();
 
             emitter.on("Foo >", () => {});
             assert.throws(
diff --git a/tests/lib/util/safe-emitter.js b/tests/lib/util/safe-emitter.js
new file mode 100644
index 000000000..7b127ea89
--- /dev/null
+++ b/tests/lib/util/safe-emitter.js
@@ -0,0 +1,43 @@
+/**
+ * @fileoverview Tests for safe-emitter
+ * @author Teddy Katz
+ */
+
+"use strict";
+
+const createEmitter = require("../../../lib/util/safe-emitter");
+const assert = require("chai").assert;
+
+describe("safe-emitter", () => {
+    describe("emit() and on()", () => {
+        it("allows listeners to be registered calls them when emitted", () => {
+            const emitter = createEmitter();
+            const colors = [];
+
+            emitter.on("foo", () => colors.push("red"));
+            emitter.on("foo", () => colors.push("blue"));
+            emitter.on("bar", () => colors.push("green"));
+
+            emitter.emit("foo");
+            assert.deepEqual(colors, ["red", "blue"]);
+
+            emitter.on("bar", color => colors.push(color));
+            emitter.emit("bar", "yellow");
+
+            assert.deepEqual(colors, ["red", "blue", "green", "yellow"]);
+        });
+
+        it("calls listeners with no `this` value", () => {
+            const emitter = createEmitter();
+            let called = false;
+
+            emitter.on("foo", function() {
+                assert.strictEqual(this, void 0); // eslint-disable-line no-invalid-this
+                called = true;
+            });
+
+            emitter.emit("foo");
+            assert(called);
+        });
+    });
+});